1 // Created on: 1992-05-07
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1992-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
22 #include <gce_MakeLin.hxx>
24 //=======================================================================
27 //=======================================================================
28 Standard_Boolean IntCoCo(const IntSurf_Quadric& Quad1,
29 const IntSurf_Quadric& Quad2,
30 const Standard_Real Tol,
31 Standard_Boolean& Empty,
32 Standard_Boolean& Same,
33 Standard_Boolean& Multpoint,
34 IntPatch_SequenceOfLine& slin,
35 IntPatch_SequenceOfPoint& spnt)
38 Standard_Integer i, NbSol;
39 Standard_Real U1,V1,U2,V2;
40 IntSurf_TypeTrans trans1,trans2;
41 IntAna_ResultType typint;
43 gp_Cone Co1(Quad1.Cone());
44 gp_Cone Co2(Quad2.Cone());
46 IntAna_QuadQuadGeo inter(Co1,Co2,Tol);
47 if (!inter.IsDone()) {
48 return Standard_False;
51 typint = inter.TypeInter();
52 NbSol = inter.NbSolutions();
53 Empty = Standard_False;
54 Same = Standard_False;
60 Empty = Standard_True;
70 //modified by NIZNHY-PKV Wed Nov 30 12:56:06 2005f
72 Standard_Real para, aDot;
73 gp_Pnt aPApex1, aPApex2, ptbid;
76 IntPatch_Point aPtsol;
77 Handle(IntPatch_GLine) glig;
83 IntSurf_Situation situC1, situC2;
85 linsol = inter.Line(1);
86 para =ElCLib::Parameter(linsol, aPApex1);
87 ptbid=ElCLib::Value(para+5., linsol);
88 Quad1.Parameters(aPApex1, U1, V1);
89 Quad2.Parameters(aPApex1, U2, V2);
91 aPtsol.SetValue(aPApex1, Tol, Standard_False);
92 aPtsol.SetParameters(U1, V1, U2, V2);
93 aPtsol.SetParameter(para);
95 NormC1=Quad1.Normale(ptbid);
96 NormC2=Quad2.Normale(ptbid);
97 aDot=NormC1.Dot(NormC2);
99 situC1=IntSurf_Outside;
100 situC2=IntSurf_Outside;
103 Standard_Real aR1, aR2;
104 gp_Lin aLAx1(aPApex1, Co1.Axis().Direction());
105 gp_Lin aLAx2(aPApex2, Co2.Axis().Direction());
107 aR1=aLAx1.Distance(ptbid);
108 aR2=aLAx2.Distance(ptbid);
110 situC1=IntSurf_Inside;
111 situC2=IntSurf_Outside;
112 if (aR1>aR2) { // Intersection line parametrizes from Apex1 to Apex2,
113 situC1=IntSurf_Outside; // So the distance betwee ptbid and aLAx1 is greater than the
114 situC2=IntSurf_Inside; // distance between ptbid and aLAx2 and in that case Cone2
119 glig=new IntPatch_GLine(linsol, Standard_True, situC1, situC2);
120 glig->AddVertex(aPtsol);
121 glig->SetFirstPoint(1);
124 linsol.SetDirection(linsol.Direction().Reversed());
125 para =ElCLib::Parameter(linsol, aPApex1);
126 aPtsol.SetParameter(para);
128 glig = new IntPatch_GLine(linsol, Standard_True, situC2, situC1);
129 glig->AddVertex(aPtsol);
130 glig->SetFirstPoint(1);
133 //////////////////////
136 for (i=1; i<=2; ++i) {
137 linsol = inter.Line(i);
138 para =ElCLib::Parameter(linsol, aPApex1);
139 ptbid=ElCLib::Value(para+5., linsol);
140 Quad1.Parameters(aPApex1, U1, V1);
141 Quad2.Parameters(aPApex1, U2, V2);
144 trans2 = IntSurf_Out;
145 if (linsol.Direction().
146 DotCross(Quad2.Normale(ptbid),Quad1.Normale(ptbid)) >0.) {
147 trans1 = IntSurf_Out;
151 Multpoint = Standard_True;
153 aPtsol.SetValue(aPApex1, Tol, Standard_False);
154 aPtsol.SetParameters(U1,V1,U2,V2);
155 aPtsol.SetParameter(para);
156 aPtsol.SetMultiple(Standard_True);
158 glig = new IntPatch_GLine(linsol, Standard_False, trans1, trans2);
159 glig->AddVertex(aPtsol);
160 glig->SetFirstPoint(1);
163 linsol.SetDirection(linsol.Direction().Reversed());
164 para = ElCLib::Parameter(linsol, aPApex1);
165 aPtsol.SetParameter(para);
166 glig = new IntPatch_GLine(linsol, Standard_False, trans1, trans2);
167 glig->AddVertex(aPtsol);
168 glig->SetFirstPoint(1);
171 } //for (i=1; i<=2; ++i)
172 } //else if (NbSol==2)
175 //modified by NIZNHY-PKV Wed Nov 30 12:56:10 2005t
177 case IntAna_Point : {
179 gp_Pnt apex1(Co1.Apex());
180 gp_Pnt apex2(Co2.Apex());
181 Standard_Real param1,param2;
182 Standard_Real paramapex1 = ElCLib::LineParameter(Co1.Axis(),apex1);
183 Standard_Real paramapex2 = ElCLib::LineParameter(Co2.Axis(),apex2);
184 for (i=1; i <= NbSol; i++) {
185 ptcontact = inter.Point(i);
186 param1 = ElCLib::LineParameter(Co1.Axis(),ptcontact);
187 param2 = ElCLib::LineParameter(Co2.Axis(),ptcontact);
189 Quad1.Parameters(ptcontact,U1,V1);
190 Quad2.Parameters(ptcontact,U2,V2);
192 if (apex1.Distance(ptcontact) <= Tol &&
193 apex2.Distance(ptcontact) <= Tol) {
194 IntPatch_Point ptsol;
195 ptsol.SetValue(ptcontact,Tol,Standard_False);
196 ptsol.SetParameters(U1,V1,U2,V2);
199 else if (param1 >= paramapex1 && param2 >= paramapex2) {
200 IntPatch_Point ptsol;
201 ptsol.SetValue(ptcontact,Tol,Standard_True);
202 ptsol.SetParameters(U1,V1,U2,V2);
212 IntPatch_Point aPtsol;
215 for (i = 1; i <= NbSol; i++) {
216 gp_Circ cirsol = inter.Circle(i);
217 ElCLib::D1(0.,cirsol,ptref,Tgt);
218 Standard_Real qwe=Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
219 if(qwe> 0.00000001) {
220 trans1 = IntSurf_Out;
223 else if(qwe<-0.00000001){
225 trans2 = IntSurf_Out;
228 trans1=trans2=IntSurf_Undecided;
230 Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
231 if(inter.HasCommonGen()) {
232 const gp_Pnt& aPChar = inter.PChar();
233 Quad1.Parameters(aPChar, U1, V1);
234 Quad2.Parameters(aPChar, U2, V2);
235 aPtsol.SetValue(aPChar, Tol, Standard_False);
236 aPtsol.SetParameters(U1, V1, U2, V2);
237 para = ElCLib::Parameter(cirsol, aPChar);
238 aPtsol.SetParameter(0.);
239 glig->AddVertex(aPtsol);
250 IntPatch_Point aPtsol;
251 gp_Elips elipsol = inter.Ellipse(1);
255 ElCLib::D1(0.,elipsol,ptref,Tgt);
257 Standard_Real qwe=Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
258 if(qwe> 0.00000001) {
259 trans1 = IntSurf_Out;
262 else if(qwe<-0.00000001) {
264 trans2 = IntSurf_Out;
267 trans1=trans2=IntSurf_Undecided;
269 Handle(IntPatch_GLine) glig = new IntPatch_GLine(elipsol,Standard_False,trans1,trans2);
270 if(inter.HasCommonGen()) {
271 const gp_Pnt& aPChar = inter.PChar();
272 Quad1.Parameters(aPChar, U1, V1);
273 Quad2.Parameters(aPChar, U2, V2);
274 aPtsol.SetValue(aPChar, Tol, Standard_False);
275 aPtsol.SetParameters(U1, V1, U2, V2);
276 para = ElCLib::Parameter(elipsol, aPChar);
277 aPtsol.SetParameter(0.);
278 glig->AddVertex(aPtsol);
286 case IntAna_Hyperbola:
289 IntPatch_Point aPtsol;
292 for(i=1; i<=2; i++) {
293 gp_Hypr hyprsol = inter.Hyperbola(i);
294 ElCLib::D1(0.,hyprsol,ptref,Tgt);
295 Standard_Real qwe=Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
296 if(qwe> 0.00000001) {
297 trans1 = IntSurf_Out;
300 else if(qwe<-0.00000001){
302 trans2 = IntSurf_Out;
305 trans1=trans2=IntSurf_Undecided;
307 Handle(IntPatch_GLine) glig = new IntPatch_GLine(hyprsol,Standard_False,trans1,trans2);
308 if(inter.HasCommonGen()) {
309 const gp_Pnt& aPChar = inter.PChar();
310 Quad1.Parameters(aPChar, U1, V1);
311 Quad2.Parameters(aPChar, U2, V2);
312 aPtsol.SetValue(aPChar, Tol, Standard_False);
313 aPtsol.SetParameters(U1, V1, U2, V2);
314 para = ElCLib::Parameter(hyprsol, aPChar);
315 aPtsol.SetParameter(0.);
316 glig->AddVertex(aPtsol);
323 case IntAna_Parabola:
326 IntPatch_Point aPtsol;
327 gp_Parab parabsol = inter.Parabola(1);
329 gp_Vec Tgtorig(parabsol.YAxis().Direction());
330 Standard_Real ptran = Tgtorig.DotCross(Quad2.Normale(parabsol.Location()),
331 Quad1.Normale(parabsol.Location()));
332 if (ptran >0.00000001) {
333 trans1 = IntSurf_Out;
336 else if (ptran <-0.00000001) {
338 trans2 = IntSurf_Out;
341 trans1=trans2=IntSurf_Undecided;
344 Handle(IntPatch_GLine) glig = new IntPatch_GLine(parabsol,Standard_False,trans1,trans2);
345 if(inter.HasCommonGen()) {
346 const gp_Pnt& aPChar = inter.PChar();
347 Quad1.Parameters(aPChar, U1, V1);
348 Quad2.Parameters(aPChar, U2, V2);
349 aPtsol.SetValue(aPChar, Tol, Standard_False);
350 aPtsol.SetParameters(U1, V1, U2, V2);
351 para = ElCLib::Parameter(parabsol, aPChar);
352 aPtsol.SetParameter(0.);
353 glig->AddVertex(aPtsol);
360 case IntAna_NoGeometricSolution:
363 IntAna_IntQuadQuad anaint(Co1,Co2,Tol);
364 if (!anaint.IsDone()) {
365 return Standard_False;
368 if (anaint.NbPnt() == 0 && anaint.NbCurve() == 0) {
369 Empty = Standard_True;
372 NbSol = anaint.NbPnt();
373 for (i = 1; i <= NbSol; i++) {
374 psol = anaint.Point(i);
375 Quad1.Parameters(psol,U1,V1);
376 Quad2.Parameters(psol,U2,V2);
377 IntPatch_Point ptsol;
378 ptsol.SetValue(psol,Tol,Standard_True);
379 ptsol.SetParameters(U1,V1,U2,V2);
383 gp_Pnt ptvalid, ptf, ptl;
386 Standard_Real first,last,para;
387 Standard_Boolean tgfound,firstp,lastp,kept;
388 Standard_Integer kount;
390 NbSol = anaint.NbCurve();
391 for (i = 1; i <= NbSol; i++) {
392 Handle(IntPatch_ALine) alig;
393 kept = Standard_False;
394 IntAna_Curve curvsol = anaint.Curve(i);
395 curvsol.Domain(first,last);
396 firstp = !curvsol.IsFirstOpen();
397 lastp = !curvsol.IsLastOpen();
399 ptf = curvsol.Value(first);
402 ptl = curvsol.Value(last);
406 tgfound = Standard_False;
409 para = (1.123*first + para)/2.123;
410 tgfound = curvsol.D1u(para,ptvalid,tgvalid);
411 if(tgvalid.SquareMagnitude() < 1e-14) {
412 //-- on se trouve ds un cas ou les normales n'auront pas de sens
413 tgfound = Standard_False;
422 Standard_Real qwe= tgvalid.DotCross(Quad2.Normale(ptvalid),
423 Quad1.Normale(ptvalid));
424 if(qwe > 0.000000001) {
425 trans1 = IntSurf_Out;
428 else if(qwe < -0.000000001) {
430 trans2 = IntSurf_Out;
433 trans1=trans2=IntSurf_Undecided;
435 alig = new IntPatch_ALine(curvsol,Standard_False,trans1,trans2);
436 kept = Standard_True;
439 ptvalid = curvsol.Value(para);
440 alig = new IntPatch_ALine(curvsol,Standard_False);
441 kept = Standard_True;
442 //-- cout << "Transition indeterminee" << endl;
445 Standard_Boolean Nfirstp = !firstp;
446 Standard_Boolean Nlastp = !lastp;
447 ProcessBounds(alig,slin,Quad1,Quad2,Nfirstp,ptf,first,
448 Nlastp,ptl,last,Multpoint,Tol);
458 return Standard_False;
462 //When two cones have common generatrix passing trough apexes
463 //it is necessary to add it is solution
464 if(inter.HasCommonGen()) {
466 IntPatch_Point aPtsol;
467 gp_Pnt aPApex1, aPApex2;
470 //common generatrix of cones
471 gce_MakeLin aMkLin(aPApex1, aPApex2);
472 const gp_Lin& linsol = aMkLin.Value();
473 Handle(IntPatch_GLine) glig =
474 new IntPatch_GLine(linsol,Standard_True,IntSurf_Undecided,IntSurf_Undecided);
476 const gp_Pnt& aPChar = inter.PChar();
477 Quad1.Parameters(aPChar, U1, V1);
478 Quad2.Parameters(aPChar, U2, V2);
479 aPtsol.SetValue(aPChar, Tol, Standard_False);
480 aPtsol.SetParameters(U1, V1, U2, V2);
481 para = ElCLib::Parameter(linsol, aPChar);
482 aPtsol.SetParameter(para);
483 glig->AddVertex(aPtsol);
489 return Standard_True;
491 //=======================================================================
494 //=======================================================================
495 Standard_Boolean IntCoSp(const IntSurf_Quadric& Quad1,
496 const IntSurf_Quadric& Quad2,
497 const Standard_Real Tol,
498 const Standard_Boolean Reversed,
499 Standard_Boolean& Empty,
500 Standard_Boolean& Multpoint,
501 IntPatch_SequenceOfLine& slin,
502 IntPatch_SequenceOfPoint& spnt)
508 IntSurf_TypeTrans trans1,trans2;
509 IntAna_ResultType typint;
513 Standard_Real U1,V1,U2,V2;
523 IntAna_QuadQuadGeo inter(Sp,Co,Tol);
525 if (!inter.IsDone()) {return Standard_False;}
527 typint = inter.TypeInter();
528 Standard_Integer NbSol = inter.NbSolutions();
529 Empty = Standard_False;
535 Empty = Standard_True;
542 gp_Pnt apex(Co.Apex());
544 Standard_Real paramapex = ElCLib::LineParameter(Co.Axis(),apex);
545 for (i=1; i <= NbSol; i++) {
546 ptcontact = inter.Point(i);
547 param = ElCLib::LineParameter(Co.Axis(),ptcontact);
548 Quad1.Parameters(ptcontact,U1,V1);
549 Quad2.Parameters(ptcontact,U2,V2);
551 if (apex.Distance(ptcontact) <= Tol) {
552 IntPatch_Point ptsol;
553 ptsol.SetValue(ptcontact,Tol,Standard_False);
554 ptsol.SetParameters(U1,V1,U2,V2);
557 else if (param >= paramapex) {
558 IntPatch_Point ptsol;
559 ptsol.SetValue(ptcontact,Tol,Standard_True);
560 ptsol.SetParameters(U1,V1,U2,V2);
574 gp_Pnt apex(Co.Apex());
575 //Standard_Real param;
576 Standard_Real paramapex = ElCLib::LineParameter(Co.Axis(),apex);
579 for (i=1; i<=NbSol; i++) {
580 gp_Circ cirsol = inter.Circle(i);
581 //-- param = ElCLib::LineParameter(Co.Axis(),
582 //-- cirsol.Location());
583 //-- if (param >= paramapex) {
585 ElCLib::D1(0.,cirsol,ptref,Tgt);
586 Standard_Real qwe = Tgt.DotCross(Quad2.Normale(ptref),
587 Quad1.Normale(ptref));
588 if(qwe> 0.00000001) {
589 trans1 = IntSurf_Out;
592 else if(qwe< -0.00000001) {
594 trans2 = IntSurf_Out;
597 trans1=trans2=IntSurf_Undecided;
599 Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
606 case IntAna_PointAndCircle:
610 gp_Pnt apex(Co.Apex());
612 Standard_Real paramapex = ElCLib::LineParameter(Co.Axis(),apex);
614 // le point est necessairement l apex
615 Quad1.Parameters(apex,U1,V1);
616 Quad2.Parameters(apex,U2,V2);
617 IntPatch_Point ptsol;
618 ptsol.SetValue(apex,Tol,Standard_False);
619 ptsol.SetParameters(U1,V1,U2,V2);
622 gp_Circ cirsol = inter.Circle(1);
623 param = ElCLib::LineParameter(Co.Axis(),
625 if (param >= paramapex) {
627 ElCLib::D1(0.,cirsol,ptref,Tgt);
628 Standard_Real qwe = Tgt.DotCross(Quad2.Normale(ptref),
629 Quad1.Normale(ptref));
630 if(qwe> 0.000000001) {
631 trans1 = IntSurf_Out;
634 else if(qwe< -0.000000001){
636 trans2 = IntSurf_Out;
639 trans1=trans2=IntSurf_Undecided;
641 Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
647 case IntAna_NoGeometricSolution:
650 IntAna_IntQuadQuad anaint(Co,Sp,Tol);
651 if (!anaint.IsDone()) {
652 return Standard_False;
655 if (anaint.NbPnt()==0 && anaint.NbCurve()==0) {
656 Empty = Standard_True;
659 NbSol = anaint.NbPnt();
660 for (i = 1; i <= NbSol; i++) {
661 psol = anaint.Point(i);
662 Quad1.Parameters(psol,U1,V1);
663 Quad2.Parameters(psol,U2,V2);
664 IntPatch_Point ptsol;
665 ptsol.SetValue(psol,Tol,Standard_True);
666 ptsol.SetParameters(U1,V1,U2,V2);
670 gp_Pnt ptvalid, ptf, ptl;
673 Standard_Real paramapex =
675 ElCLib::LineParameter(Co.Axis(),
677 Standard_Real first,last,para;
678 Standard_Boolean tgfound,firstp,lastp,kept;
679 Standard_Integer kount;
681 NbSol = anaint.NbCurve();
682 for (i = 1; i <= NbSol; i++) {
683 Handle(IntPatch_ALine) alig;
684 kept = Standard_False;
685 IntAna_Curve curvsol = anaint.Curve(i);
686 curvsol.Domain(first,last);
687 firstp = !curvsol.IsFirstOpen();
688 lastp = !curvsol.IsLastOpen();
690 ptf = curvsol.Value(first);
693 ptl = curvsol.Value(last);
697 tgfound = Standard_False;
700 para = (1.123*first + para)/2.123;
701 tgfound = curvsol.D1u(para,ptvalid,tgvalid);
708 para = ElCLib::LineParameter(Co.Axis(),ptvalid);
709 Standard_Real qwe = tgvalid.DotCross(Quad2.Normale(ptvalid),
710 Quad1.Normale(ptvalid));
711 if(qwe> 0.000000001) {
712 trans1 = IntSurf_Out;
715 else if(qwe<-0.000000001) {
717 trans2 = IntSurf_Out;
720 trans1=trans2=IntSurf_Undecided;
722 alig = new IntPatch_ALine(curvsol,Standard_False,trans1,trans2);
723 kept = Standard_True;
726 ptvalid = curvsol.Value(para);
727 para = ElCLib::LineParameter(Co.Axis(),ptvalid);
728 alig = new IntPatch_ALine(curvsol,Standard_False);
729 kept = Standard_True;
730 //-- cout << "Transition indeterminee" << endl;
733 Standard_Boolean Nfirstp = !firstp;
734 Standard_Boolean Nlastp = !lastp;
735 ProcessBounds(alig,slin,Quad1,Quad2,Nfirstp,ptf,first,
736 Nlastp,ptl,last,Multpoint,Tol);
746 return Standard_False;
750 return Standard_True;
752 //=======================================================================
755 //=======================================================================
756 Standard_Boolean IntSpSp(const IntSurf_Quadric& Quad1,
757 const IntSurf_Quadric& Quad2,
758 const Standard_Real Tol,
759 Standard_Boolean& Empty,
760 Standard_Boolean& Same,
761 IntPatch_SequenceOfLine& slin,
762 IntPatch_SequenceOfPoint& spnt)
764 // Traitement du cas Sphere/Sphere
767 IntSurf_TypeTrans trans1,trans2;
768 IntAna_ResultType typint;
769 gp_Sphere sph1(Quad1.Sphere());
770 gp_Sphere sph2(Quad2.Sphere());
772 IntAna_QuadQuadGeo inter(sph1,sph2,Tol);
773 if (!inter.IsDone()) {return Standard_False;}
775 typint = inter.TypeInter();
776 Empty = Standard_False;
777 Same = Standard_False;
783 Empty = Standard_True;
789 Same = Standard_True;
795 gp_Pnt psol(inter.Point(1));
796 Standard_Real U1,V1,U2,V2;
797 Quad1.Parameters(psol,U1,V1);
798 Quad2.Parameters(psol,U2,V2);
799 IntPatch_Point ptsol;
800 ptsol.SetValue(psol,Tol,Standard_True);
801 ptsol.SetParameters(U1,V1,U2,V2);
808 gp_Circ cirsol = inter.Circle(1);
811 ElCLib::D1(0.,cirsol,ptref,Tgt);
813 Standard_Real qwe=Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
815 trans1 = IntSurf_Out;
818 else if(qwe<-0.00000001) {
820 trans2 = IntSurf_Out;
823 trans1=trans2=IntSurf_Undecided;
825 Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
832 return Standard_False; // on ne doit pas passer ici
835 return Standard_True;