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 //modified by NIZNHY-PKV Thu Sep 15 11:09:12 2011
19 void SeamPosition(const gp_Pnt& aPLoc,
23 void AdjustToSeam (const gp_Cylinder& aQuad,
26 void AdjustToSeam (const gp_Sphere& aQuad,
28 const Standard_Real aTolAng);
30 void AdjustToSeam (const gp_Cone& aQuad,
33 void AdjustToSeam (const gp_Torus& aQuad,
35 //modified by NIZNHY-PKV Thu Sep 15 11:09:13 2011
37 //=======================================================================
40 // Traitement du cas Plan/Plan
41 //=======================================================================
42 Standard_Boolean IntPP (const IntSurf_Quadric& Quad1,
43 const IntSurf_Quadric& Quad2,
44 const Standard_Real Tolang,
45 const Standard_Real TolTang,
46 Standard_Boolean& Same,
47 IntPatch_SequenceOfLine& slin)
50 IntSurf_TypeTrans trans1,trans2;
51 IntAna_ResultType typint;
52 gp_Pln pl1(Quad1.Plane());
53 gp_Pln pl2(Quad2.Plane());
55 IntAna_QuadQuadGeo inter(pl1,pl2,Tolang,TolTang);
56 if (!inter.IsDone()) {return Standard_False;}
57 Same = Standard_False;
58 typint = inter.TypeInter();
59 if (typint == IntAna_Same) { // cas faces confondues
62 else if (typint != IntAna_Empty) { // on a une ligne
63 gp_Lin linsol = inter.Line(1);
64 Standard_Real discri = linsol.Direction().DotCross
65 (Quad2.Normale(linsol.Location()),
66 Quad1.Normale(linsol.Location()));
76 Handle(IntPatch_GLine) glig =
77 new IntPatch_GLine (linsol,Standard_False,trans1,trans2);
82 //=======================================================================
85 // Traitement du cas Plan/Cylindre et reciproquement
86 //=======================================================================
87 Standard_Boolean IntPCy (const IntSurf_Quadric& Quad1,
88 const IntSurf_Quadric& Quad2,
89 const Standard_Real Tolang,
90 const Standard_Real TolTang,
91 const Standard_Boolean Reversed,
92 Standard_Boolean& Empty,
93 IntPatch_SequenceOfLine& slin,
94 const Standard_Real H)
100 IntSurf_TypeTrans trans1,trans2;
101 IntAna_ResultType typint;
103 IntAna_QuadQuadGeo inter;
106 Cy = Quad2.Cylinder();
110 Cy = Quad1.Cylinder();
112 inter.Perform(Pl,Cy,Tolang,TolTang,H);
113 if (!inter.IsDone()) {return Standard_False;}
114 typint = inter.TypeInter();
115 Standard_Integer NbSol = inter.NbSolutions();
116 Empty = Standard_False;
120 case IntAna_Empty : {
121 Empty = Standard_True;
126 gp_Lin linsol = inter.Line(1);
127 gp_Pnt orig(linsol.Location());
128 if (NbSol == 1) { // ligne de tangence
129 gp_Vec TestCurvature(orig,Cy.Location());
130 gp_Vec Normp,Normcyl;
132 Normp = Quad1.Normale(orig);
133 Normcyl = Quad2.Normale(orig);
136 Normp = Quad2.Normale(orig);
137 Normcyl = Quad1.Normale(orig);
140 IntSurf_Situation situcyl;
141 IntSurf_Situation situp;
143 if (Normp.Dot(TestCurvature) > 0.) {
144 situcyl = IntSurf_Outside;
145 if (Normp.Dot(Normcyl) > 0.) {
146 situp = IntSurf_Inside;
149 situp = IntSurf_Outside;
153 situcyl = IntSurf_Inside;
154 if (Normp.Dot(Normcyl) > 0.) {
155 situp = IntSurf_Outside;
158 situp = IntSurf_Inside;
161 Handle(IntPatch_GLine) glig;
163 glig = new IntPatch_GLine(linsol, Standard_True, situp, situcyl);
166 glig = new IntPatch_GLine(linsol, Standard_True, situcyl, situp);
171 // on a 2 droites. Il faut determiner les transitions
174 if (linsol.Direction().DotCross(Quad2.Normale(orig),
175 Quad1.Normale(orig)) >0.) {
176 trans1 = IntSurf_Out;
181 trans2 = IntSurf_Out;
183 Handle(IntPatch_GLine) glig =
184 new IntPatch_GLine(linsol, Standard_False,trans1,trans2);
187 linsol = inter.Line(2);
188 orig = linsol.Location();
190 if (linsol.Direction().DotCross(Quad2.Normale(orig),
191 Quad1.Normale(orig)) >0.) {
192 trans1 = IntSurf_Out;
197 trans2 = IntSurf_Out;
199 glig = new IntPatch_GLine(linsol, Standard_False,trans1,trans2);
205 case IntAna_Circle: {
210 cirsol = inter.Circle(1);
211 //modified by NIZNHY-PKV Thu Sep 15 11:30:03 2011f
212 AdjustToSeam(Cy, cirsol);
213 //modified by NIZNHY-PKV Thu Sep 15 11:30:15 2011t
214 ElCLib::D1(0.,cirsol,ptref,Tgt);
216 if (Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref)) > 0.0) {
217 trans1 = IntSurf_Out;
222 trans2 = IntSurf_Out;
224 Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
229 case IntAna_Ellipse: {
230 gp_Elips elipsol = inter.Ellipse(1);
233 ElCLib::D1(0.,elipsol,ptref,Tgt);
235 if (Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref)) > 0.0) {
236 trans1 = IntSurf_Out;
241 trans2 = IntSurf_Out;
243 Handle(IntPatch_GLine) glig = new IntPatch_GLine(elipsol,Standard_False,trans1,trans2);
249 return Standard_False; // on ne doit pas passer ici
252 return Standard_True;
254 //=======================================================================
257 // Traitement du cas Plan/Sphere et reciproquement
258 //=======================================================================
259 Standard_Boolean IntPSp (const IntSurf_Quadric& Quad1,
260 const IntSurf_Quadric& Quad2,
261 //modified by NIZNHY-PKV Tue Sep 20 08:59:36 2011f
262 const Standard_Real Tolang,
263 //modified by NIZNHY-PKV Tue Sep 20 08:59:39 2011t
264 const Standard_Real TolTang,
265 const Standard_Boolean Reversed,
266 Standard_Boolean& Empty,
267 IntPatch_SequenceOfLine& slin,
268 IntPatch_SequenceOfPoint& spnt)
275 IntSurf_TypeTrans trans1,trans2;
276 IntAna_ResultType typint;
278 IntAna_QuadQuadGeo inter;
287 inter.Perform(Pl,Sp);
289 if (!inter.IsDone()) {return Standard_False;}
291 typint = inter.TypeInter();
292 Empty = Standard_False;
295 case IntAna_Empty : {
296 Empty = Standard_True;
301 gp_Pnt psol = inter.Point(1);
302 Standard_Real U1,V1,U2,V2;
303 Quad1.Parameters(psol,U1,V1);
304 Quad2.Parameters(psol,U2,V2);
305 IntPatch_Point ptsol;
306 ptsol.SetValue(psol,TolTang,Standard_True);
307 ptsol.SetParameters(U1,V1,U2,V2);
312 case IntAna_Circle: {
313 cirsol = inter.Circle(1);
314 //modified by NIZNHY-PKV Thu Sep 15 11:30:03 2011f
315 AdjustToSeam(Sp, cirsol, Tolang);
316 //modified by NIZNHY-PKV Thu Sep 15 11:30:15 2011t
319 ElCLib::D1(0.,cirsol,ptref,Tgt);
321 if (Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref)) >0.) {
322 trans1 = IntSurf_Out;
327 trans2 = IntSurf_Out;
329 Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
335 return Standard_False; // on ne doit pas passer ici
338 return Standard_True;
340 //=======================================================================
343 // Traitement du cas Plan/Cone et reciproquement
344 //=======================================================================
345 Standard_Boolean IntPCo (const IntSurf_Quadric& Quad1,
346 const IntSurf_Quadric& Quad2,
347 const Standard_Real Tolang,
348 const Standard_Real TolTang,
349 const Standard_Boolean Reversed,
350 Standard_Boolean& Empty,
351 Standard_Boolean& Multpoint,
352 IntPatch_SequenceOfLine& slin,
353 IntPatch_SequenceOfPoint& spnt)
362 IntSurf_TypeTrans trans1,trans2;
363 IntAna_ResultType typint;
365 IntAna_QuadQuadGeo inter;
377 inter.Perform(Pl,Co,Tolang,TolTang);
378 if (!inter.IsDone()) {
379 return Standard_False;
382 typint = inter.TypeInter();
383 Standard_Integer NbSol = inter.NbSolutions();
384 Empty = Standard_False;
388 gp_Pnt psol = inter.Point(1);
389 Standard_Real U1,V1,U2,V2;
390 Quad1.Parameters(psol,U1,V1);
391 Quad2.Parameters(psol,U2,V2);
392 IntPatch_Point ptsol;
393 ptsol.SetValue(psol,TolTang,Standard_False);
394 ptsol.SetParameters(U1,V1,U2,V2);
400 gp_Lin linsol = inter.Line(1);
401 if (linsol.Direction().Dot(Co.Axis().Direction()) <0.) {
402 linsol.SetDirection(linsol.Direction().Reversed());
404 Standard_Real para = ElCLib::Parameter(linsol, apex);
405 gp_Pnt ptbid (ElCLib::Value(para+5.,linsol));
406 Standard_Real U1,V1,U2,V2;
407 Quad1.Parameters(apex,U1,V1);
408 Quad2.Parameters(apex,U2,V2);
410 if (NbSol == 1) { // ligne de tangence
411 IntPatch_Point ptsol;
412 ptsol.SetValue(apex,TolTang,Standard_False);
413 ptsol.SetParameters(U1,V1,U2,V2);
414 ptsol.SetParameter(para);
415 gp_Pnt ptbid2(apex.XYZ() + 5.*Co.Axis().Direction().XYZ());
416 gp_Vec TestCurvature(ptbid,ptbid2);
419 Normp = Quad1.Normale(ptbid);
420 Normco = Quad2.Normale(ptbid);
423 Normp = Quad2.Normale(ptbid);
424 Normco = Quad1.Normale(ptbid);
426 IntSurf_Situation situco,situco_otherside;
427 IntSurf_Situation situp,situp_otherside;
429 if (Normp.Dot(TestCurvature) > 0.) {
430 situco = IntSurf_Outside;
431 situco_otherside = IntSurf_Inside;
432 if (Normp.Dot(Normco) > 0.) {
433 situp = IntSurf_Inside;
434 situp_otherside = IntSurf_Outside;
437 situp = IntSurf_Outside;
438 situp_otherside = IntSurf_Inside;
442 situco = IntSurf_Inside;
443 situco_otherside = IntSurf_Outside;
444 if (Normp.Dot(Normco) > 0.) {
445 situp = IntSurf_Outside;
446 situp_otherside = IntSurf_Inside;
449 situp = IntSurf_Inside;
450 situp_otherside = IntSurf_Outside;
453 //----------------------------------------------------------
454 //-- Apex ---> Cone.Direction
456 Handle(IntPatch_GLine) glig;
458 glig = new IntPatch_GLine(linsol, Standard_True, situp, situco);
461 glig = new IntPatch_GLine(linsol, Standard_True, situco, situp);
463 glig->AddVertex(ptsol);
464 glig->SetFirstPoint(1);
466 //----------------------------------------------------------
467 //-- -Cone.Direction <------- Apex
469 linsol.SetDirection(linsol.Direction().Reversed());
471 glig = new IntPatch_GLine(linsol, Standard_True, situp_otherside, situco_otherside);
474 glig = new IntPatch_GLine(linsol, Standard_True, situco_otherside, situp_otherside);
476 glig->AddVertex(ptsol);
477 glig->SetFirstPoint(1);
481 // on a 2 droites. Il faut determiner les transitions
482 // de chacune. On oriente chaque ligne dans le sens
483 // de l axe du cone. Les transitions de chaque ligne seront
484 // inverses l une de l autre => on ne fait le calcul que sur
486 if (linsol.Direction().DotCross
487 (Quad2.Normale(ptbid),Quad1.Normale(ptbid)) >0.) {
488 trans1 = IntSurf_Out;
493 trans2 = IntSurf_Out;
496 Multpoint = Standard_True;
497 //------------------------------------------- Ligne 1 -------
498 IntPatch_Point ptsol;
499 ptsol.SetValue(apex,TolTang,Standard_False);
500 ptsol.SetParameters(U1,V1,U2,V2);
501 ptsol.SetParameter(para);
502 ptsol.SetMultiple(Standard_True);
503 Handle(IntPatch_GLine) glig;
504 glig = new IntPatch_GLine(linsol, Standard_False,trans1,trans2);
505 glig->AddVertex(ptsol);
506 glig->SetFirstPoint(1);
508 //-----------------------------------------------------------
509 //-- Other Side : Les transitions restent les memes
510 //-- linsol -> -linsol et Quad1(2).N -> -Quad1(2).N
512 linsol.SetDirection(linsol.Direction().Reversed());
513 glig = new IntPatch_GLine(linsol, Standard_False,trans1,trans2);
514 para = ElCLib::Parameter(linsol, apex);
515 ptsol.SetParameter(para);
516 glig->AddVertex(ptsol);
517 glig->SetFirstPoint(1);
520 //------------------------------------------- Ligne 2 -------
521 linsol = inter.Line(2);
522 if (linsol.Direction().Dot(Co.Axis().Direction()) <0.) {
523 linsol.SetDirection(linsol.Direction().Reversed());
525 para = ElCLib::Parameter(linsol, apex);
526 ptbid = ElCLib::Value(para+5.,linsol);
527 if (linsol.Direction().DotCross
528 (Quad2.Normale(ptbid),Quad1.Normale(ptbid)) >0.) {
529 trans1 = IntSurf_Out;
534 trans2 = IntSurf_Out;
536 ptsol.SetParameter(para);
537 glig = new IntPatch_GLine(linsol, Standard_False,trans1,trans2);
538 para = ElCLib::Parameter(linsol, apex);
539 ptsol.SetParameter(para);
540 glig->AddVertex(ptsol);
541 glig->SetFirstPoint(1);
543 //-----------------------------------------------------------
544 //-- Other Side : Les transitions restent les memes
545 //-- linsol -> -linsol et Quad1(2).N -> -Quad1(2).N
547 linsol.SetDirection(linsol.Direction().Reversed());
548 glig = new IntPatch_GLine(linsol, Standard_False,trans1,trans2);
549 para = ElCLib::Parameter(linsol, apex);
550 ptsol.SetParameter(para);
551 glig->AddVertex(ptsol);
552 glig->SetFirstPoint(1);
558 case IntAna_Circle: {
559 gp_Circ cirsol = inter.Circle(1);
560 //modified by NIZNHY-PKV Thu Sep 15 11:34:04 2011f
561 AdjustToSeam(Co, cirsol);
562 //modified by NIZNHY-PKV Thu Sep 15 11:36:08 2011t
565 ElCLib::D1(0.,cirsol,ptref,Tgt);
567 if (Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref)) >0.) {
568 trans1 = IntSurf_Out;
573 trans2 = IntSurf_Out;
575 Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
580 case IntAna_Ellipse: {
581 gp_Elips elipsol = inter.Ellipse(1);
584 ElCLib::D1(0.,elipsol,ptref,Tgt);
586 if (Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref)) >0.) {
587 trans1 = IntSurf_Out;
592 trans2 = IntSurf_Out;
594 Handle(IntPatch_GLine) glig = new IntPatch_GLine(elipsol,Standard_False,trans1,trans2);
599 case IntAna_Parabola: {
600 gp_Parab parabsol = inter.Parabola(1);
602 gp_Vec Tgtorig(parabsol.YAxis().Direction());
603 Standard_Real ptran = Tgtorig.DotCross(Quad2.Normale(parabsol.Location()),
604 Quad1.Normale(parabsol.Location()));
605 if (ptran >0.00000001) {
606 trans1 = IntSurf_Out;
609 else if (ptran <-0.00000001) {
611 trans2 = IntSurf_Out;
614 trans1=trans2=IntSurf_Undecided;
616 Handle(IntPatch_GLine) glig = new IntPatch_GLine(parabsol,Standard_False,trans1,trans2);
621 case IntAna_Hyperbola: {
625 for(Standard_Integer i=1; i<=2; i++) {
626 gp_Hypr hyprsol = inter.Hyperbola(i);
627 tophypr = ElCLib::Value(hyprsol.MajorRadius(),
629 Tgttop = hyprsol.YAxis().Direction();
630 Standard_Real qwe = Tgttop.DotCross(Quad2.Normale(tophypr),
631 Quad1.Normale(tophypr));
633 if (qwe>0.00000001) {
634 trans1 = IntSurf_Out;
637 else if (qwe<-0.00000001){
639 trans2 = IntSurf_Out;
642 trans1=trans2=IntSurf_Undecided;
644 Handle(IntPatch_GLine) glig = new IntPatch_GLine(hyprsol,Standard_False,trans1,trans2);
651 return Standard_False;
654 return Standard_True;
656 //=======================================================================
659 //=======================================================================
660 Standard_Boolean IntPTo(const IntSurf_Quadric& theQuad1,
661 const IntSurf_Quadric& theQuad2,
662 const Standard_Real theTolTang,
663 const Standard_Boolean bReversed,
664 Standard_Boolean& bEmpty,
665 IntPatch_SequenceOfLine& theSeqLin)
667 const gp_Pln aPln = bReversed ? theQuad2.Plane() : theQuad1.Plane();
668 const gp_Torus aTorus = bReversed ? theQuad1.Torus() : theQuad2.Torus();
670 IntAna_QuadQuadGeo inter(aPln, aTorus, theTolTang);
671 Standard_Boolean bRet = inter.IsDone();
677 IntAna_ResultType typint = inter.TypeInter();
678 Standard_Integer NbSol = inter.NbSolutions();
679 bEmpty = Standard_False;
683 bEmpty = Standard_True;
686 case IntAna_Circle : {
688 IntSurf_TypeTrans trans1, trans2;
692 for (i = 1; i <= NbSol; ++i) {
693 gp_Circ aC = inter.Circle(i);
694 if (!aPln.Axis().IsNormal(aTorus.Axis(), Precision::Angular())) {
695 AdjustToSeam(aTorus, aC);
697 ElCLib::D1(0., aC, ptref, Tgt);
699 if (Tgt.DotCross(theQuad2.Normale(ptref),theQuad1.Normale(ptref)) > 0.0) {
700 trans1 = IntSurf_Out;
705 trans2 = IntSurf_Out;
708 Handle(IntPatch_GLine) glig =
709 new IntPatch_GLine(aC, Standard_False, trans1, trans2);
710 theSeqLin.Append(glig);
715 case IntAna_NoGeometricSolution:
717 bRet = Standard_False;
724 //modified by NIZNHY-PKV Thu Sep 15 10:53:39 2011f
725 //=======================================================================
726 //function : AdjustToSeam
728 //=======================================================================
729 void AdjustToSeam (const gp_Cone& aQuad,
734 const gp_Pnt& aPLoc=aCirc.Location();
735 const gp_Ax3& aAx3=aQuad.Position();
736 SeamPosition(aPLoc, aAx3, aAx2);
737 aCirc.SetPosition(aAx2);
739 //=======================================================================
740 //function : AdjustToSeam
742 //=======================================================================
743 void AdjustToSeam (const gp_Sphere& aQuad,
745 const Standard_Real aTolAng)
749 const gp_Ax1& aAx1C=aCirc.Axis();
750 const gp_Ax3& aAx3=aQuad.Position();
751 const gp_Ax1& aAx1Q=aAx3.Axis();
753 const gp_Dir& aDirC=aAx1C.Direction();
754 const gp_Dir& aDirQ=aAx1Q.Direction();
755 if (aDirC.IsParallel(aDirQ, aTolAng)) {
756 const gp_Pnt& aPLoc=aCirc.Location();
757 SeamPosition(aPLoc, aAx3, aAx2);
758 aCirc.SetPosition(aAx2);
761 //=======================================================================
762 //function : AdjustToSeam
764 //=======================================================================
765 void AdjustToSeam (const gp_Cylinder& aQuad,
770 const gp_Pnt& aPLoc=aCirc.Location();
771 const gp_Ax3& aAx3=aQuad.Position();
772 SeamPosition(aPLoc, aAx3, aAx2);
773 aCirc.SetPosition(aAx2);
775 //=======================================================================
776 //function : AdjustToSeam
778 //=======================================================================
779 void AdjustToSeam (const gp_Torus& aQuad,
784 const gp_Pnt& aPLoc=aCirc.Location();
785 const gp_Ax3& aAx3=aQuad.Position();
786 SeamPosition(aPLoc, aAx3, aAx2);
787 aCirc.SetPosition(aAx2);
789 //=======================================================================
790 //function : SeamPosition
792 //=======================================================================
793 void SeamPosition(const gp_Pnt& aPLoc,
797 const gp_Dir& aDZ=aPos.Direction();
798 const gp_Dir& aDX=aPos.XDirection();
799 gp_Ax2 aAx2(aPLoc, aDZ, aDX);
803 //modified by NIZNHY-PKV Thu Sep 15 10:53:41 2011t