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 //modified by NIZNHY-PKV Thu Sep 15 11:09:12 2011
24 void SeamPosition(const gp_Pnt& aPLoc,
28 void AdjustToSeam (const gp_Cylinder& aQuad,
31 void AdjustToSeam (const gp_Sphere& aQuad,
33 const Standard_Real aTolAng);
35 void AdjustToSeam (const gp_Cone& aQuad,
37 //modified by NIZNHY-PKV Thu Sep 15 11:09:13 2011
39 //=======================================================================
42 // Traitement du cas Plan/Plan
43 //=======================================================================
44 Standard_Boolean IntPP (const IntSurf_Quadric& Quad1,
45 const IntSurf_Quadric& Quad2,
46 const Standard_Real Tolang,
47 const Standard_Real TolTang,
48 Standard_Boolean& Same,
49 IntPatch_SequenceOfLine& slin)
52 IntSurf_TypeTrans trans1,trans2;
53 IntAna_ResultType typint;
54 gp_Pln pl1(Quad1.Plane());
55 gp_Pln pl2(Quad2.Plane());
57 IntAna_QuadQuadGeo inter(pl1,pl2,Tolang,TolTang);
58 if (!inter.IsDone()) {return Standard_False;}
59 Same = Standard_False;
60 typint = inter.TypeInter();
61 if (typint == IntAna_Same) { // cas faces confondues
64 else if (typint != IntAna_Empty) { // on a une ligne
65 gp_Lin linsol = inter.Line(1);
66 Standard_Real discri = linsol.Direction().DotCross
67 (Quad2.Normale(linsol.Location()),
68 Quad1.Normale(linsol.Location()));
78 Handle(IntPatch_GLine) glig =
79 new IntPatch_GLine (linsol,Standard_False,trans1,trans2);
84 //=======================================================================
87 // Traitement du cas Plan/Cylindre et reciproquement
88 //=======================================================================
89 Standard_Boolean IntPCy (const IntSurf_Quadric& Quad1,
90 const IntSurf_Quadric& Quad2,
91 const Standard_Real Tolang,
92 const Standard_Real TolTang,
93 const Standard_Boolean Reversed,
94 Standard_Boolean& Empty,
95 IntPatch_SequenceOfLine& slin,
96 const Standard_Real H)
102 IntSurf_TypeTrans trans1,trans2;
103 IntAna_ResultType typint;
105 IntAna_QuadQuadGeo inter;
108 Cy = Quad2.Cylinder();
112 Cy = Quad1.Cylinder();
114 inter.Perform(Pl,Cy,Tolang,TolTang,H);
115 if (!inter.IsDone()) {return Standard_False;}
116 typint = inter.TypeInter();
117 Standard_Integer NbSol = inter.NbSolutions();
118 Empty = Standard_False;
122 case IntAna_Empty : {
123 Empty = Standard_True;
128 gp_Lin linsol = inter.Line(1);
129 gp_Pnt orig(linsol.Location());
130 if (NbSol == 1) { // ligne de tangence
131 gp_Vec TestCurvature(orig,Cy.Location());
132 gp_Vec Normp,Normcyl;
134 Normp = Quad1.Normale(orig);
135 Normcyl = Quad2.Normale(orig);
138 Normp = Quad2.Normale(orig);
139 Normcyl = Quad1.Normale(orig);
142 IntSurf_Situation situcyl;
143 IntSurf_Situation situp;
145 if (Normp.Dot(TestCurvature) > 0.) {
146 situcyl = IntSurf_Outside;
147 if (Normp.Dot(Normcyl) > 0.) {
148 situp = IntSurf_Inside;
151 situp = IntSurf_Outside;
155 situcyl = IntSurf_Inside;
156 if (Normp.Dot(Normcyl) > 0.) {
157 situp = IntSurf_Outside;
160 situp = IntSurf_Inside;
163 Handle(IntPatch_GLine) glig;
165 glig = new IntPatch_GLine(linsol, Standard_True, situp, situcyl);
168 glig = new IntPatch_GLine(linsol, Standard_True, situcyl, situp);
173 // on a 2 droites. Il faut determiner les transitions
176 if (linsol.Direction().DotCross(Quad2.Normale(orig),
177 Quad1.Normale(orig)) >0.) {
178 trans1 = IntSurf_Out;
183 trans2 = IntSurf_Out;
185 Handle(IntPatch_GLine) glig =
186 new IntPatch_GLine(linsol, Standard_False,trans1,trans2);
189 linsol = inter.Line(2);
190 orig = linsol.Location();
192 if (linsol.Direction().DotCross(Quad2.Normale(orig),
193 Quad1.Normale(orig)) >0.) {
194 trans1 = IntSurf_Out;
199 trans2 = IntSurf_Out;
201 glig = new IntPatch_GLine(linsol, Standard_False,trans1,trans2);
207 case IntAna_Circle: {
212 cirsol = inter.Circle(1);
213 //modified by NIZNHY-PKV Thu Sep 15 11:30:03 2011f
214 AdjustToSeam(Cy, cirsol);
215 //modified by NIZNHY-PKV Thu Sep 15 11:30:15 2011t
216 ElCLib::D1(0.,cirsol,ptref,Tgt);
218 if (Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref)) > 0.0) {
219 trans1 = IntSurf_Out;
224 trans2 = IntSurf_Out;
226 Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
231 case IntAna_Ellipse: {
232 gp_Elips elipsol = inter.Ellipse(1);
235 ElCLib::D1(0.,elipsol,ptref,Tgt);
237 if (Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref)) > 0.0) {
238 trans1 = IntSurf_Out;
243 trans2 = IntSurf_Out;
245 Handle(IntPatch_GLine) glig = new IntPatch_GLine(elipsol,Standard_False,trans1,trans2);
251 return Standard_False; // on ne doit pas passer ici
254 return Standard_True;
256 //=======================================================================
259 // Traitement du cas Plan/Sphere et reciproquement
260 //=======================================================================
261 Standard_Boolean IntPSp (const IntSurf_Quadric& Quad1,
262 const IntSurf_Quadric& Quad2,
263 //modified by NIZNHY-PKV Tue Sep 20 08:59:36 2011f
264 const Standard_Real Tolang,
265 //modified by NIZNHY-PKV Tue Sep 20 08:59:39 2011t
266 const Standard_Real TolTang,
267 const Standard_Boolean Reversed,
268 Standard_Boolean& Empty,
269 IntPatch_SequenceOfLine& slin,
270 IntPatch_SequenceOfPoint& spnt)
277 IntSurf_TypeTrans trans1,trans2;
278 IntAna_ResultType typint;
280 IntAna_QuadQuadGeo inter;
289 inter.Perform(Pl,Sp);
291 if (!inter.IsDone()) {return Standard_False;}
293 typint = inter.TypeInter();
294 Empty = Standard_False;
297 case IntAna_Empty : {
298 Empty = Standard_True;
303 gp_Pnt psol = inter.Point(1);
304 Standard_Real U1,V1,U2,V2;
305 Quad1.Parameters(psol,U1,V1);
306 Quad2.Parameters(psol,U2,V2);
307 IntPatch_Point ptsol;
308 ptsol.SetValue(psol,TolTang,Standard_True);
309 ptsol.SetParameters(U1,V1,U2,V2);
314 case IntAna_Circle: {
315 cirsol = inter.Circle(1);
316 //modified by NIZNHY-PKV Thu Sep 15 11:30:03 2011f
317 AdjustToSeam(Sp, cirsol, Tolang);
318 //modified by NIZNHY-PKV Thu Sep 15 11:30:15 2011t
321 ElCLib::D1(0.,cirsol,ptref,Tgt);
323 if (Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref)) >0.) {
324 trans1 = IntSurf_Out;
329 trans2 = IntSurf_Out;
331 Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
337 return Standard_False; // on ne doit pas passer ici
340 return Standard_True;
342 //=======================================================================
345 // Traitement du cas Plan/Cone et reciproquement
346 //=======================================================================
347 Standard_Boolean IntPCo (const IntSurf_Quadric& Quad1,
348 const IntSurf_Quadric& Quad2,
349 const Standard_Real Tolang,
350 const Standard_Real TolTang,
351 const Standard_Boolean Reversed,
352 Standard_Boolean& Empty,
353 Standard_Boolean& Multpoint,
354 IntPatch_SequenceOfLine& slin,
355 IntPatch_SequenceOfPoint& spnt)
364 IntSurf_TypeTrans trans1,trans2;
365 IntAna_ResultType typint;
367 IntAna_QuadQuadGeo inter;
379 inter.Perform(Pl,Co,Tolang,TolTang);
380 if (!inter.IsDone()) {
381 return Standard_False;
384 typint = inter.TypeInter();
385 Standard_Integer NbSol = inter.NbSolutions();
386 Empty = Standard_False;
390 gp_Pnt psol = inter.Point(1);
391 Standard_Real U1,V1,U2,V2;
392 Quad1.Parameters(psol,U1,V1);
393 Quad2.Parameters(psol,U2,V2);
394 IntPatch_Point ptsol;
395 ptsol.SetValue(psol,TolTang,Standard_False);
396 ptsol.SetParameters(U1,V1,U2,V2);
402 gp_Lin linsol = inter.Line(1);
403 if (linsol.Direction().Dot(Co.Axis().Direction()) <0.) {
404 linsol.SetDirection(linsol.Direction().Reversed());
406 Standard_Real para = ElCLib::Parameter(linsol, apex);
407 gp_Pnt ptbid (ElCLib::Value(para+5.,linsol));
408 Standard_Real U1,V1,U2,V2;
409 Quad1.Parameters(apex,U1,V1);
410 Quad2.Parameters(apex,U2,V2);
412 if (NbSol == 1) { // ligne de tangence
413 IntPatch_Point ptsol;
414 ptsol.SetValue(apex,TolTang,Standard_False);
415 ptsol.SetParameters(U1,V1,U2,V2);
416 ptsol.SetParameter(para);
417 gp_Pnt ptbid2(apex.XYZ() + 5.*Co.Axis().Direction().XYZ());
418 gp_Vec TestCurvature(ptbid,ptbid2);
421 Normp = Quad1.Normale(ptbid);
422 Normco = Quad2.Normale(ptbid);
425 Normp = Quad2.Normale(ptbid);
426 Normco = Quad1.Normale(ptbid);
428 IntSurf_Situation situco,situco_otherside;
429 IntSurf_Situation situp,situp_otherside;
431 if (Normp.Dot(TestCurvature) > 0.) {
432 situco = IntSurf_Outside;
433 situco_otherside = IntSurf_Inside;
434 if (Normp.Dot(Normco) > 0.) {
435 situp = IntSurf_Inside;
436 situp_otherside = IntSurf_Outside;
439 situp = IntSurf_Outside;
440 situp_otherside = IntSurf_Inside;
444 situco = IntSurf_Inside;
445 situco_otherside = IntSurf_Outside;
446 if (Normp.Dot(Normco) > 0.) {
447 situp = IntSurf_Outside;
448 situp_otherside = IntSurf_Inside;
451 situp = IntSurf_Inside;
452 situp_otherside = IntSurf_Outside;
455 //----------------------------------------------------------
456 //-- Apex ---> Cone.Direction
458 Handle(IntPatch_GLine) glig;
460 glig = new IntPatch_GLine(linsol, Standard_True, situp, situco);
463 glig = new IntPatch_GLine(linsol, Standard_True, situco, situp);
465 glig->AddVertex(ptsol);
466 glig->SetFirstPoint(1);
468 //----------------------------------------------------------
469 //-- -Cone.Direction <------- Apex
471 linsol.SetDirection(linsol.Direction().Reversed());
473 glig = new IntPatch_GLine(linsol, Standard_True, situp_otherside, situco_otherside);
476 glig = new IntPatch_GLine(linsol, Standard_True, situco_otherside, situp_otherside);
478 glig->AddVertex(ptsol);
479 glig->SetFirstPoint(1);
483 // on a 2 droites. Il faut determiner les transitions
484 // de chacune. On oriente chaque ligne dans le sens
485 // de l axe du cone. Les transitions de chaque ligne seront
486 // inverses l une de l autre => on ne fait le calcul que sur
488 if (linsol.Direction().DotCross
489 (Quad2.Normale(ptbid),Quad1.Normale(ptbid)) >0.) {
490 trans1 = IntSurf_Out;
495 trans2 = IntSurf_Out;
498 Multpoint = Standard_True;
499 //------------------------------------------- Ligne 1 -------
500 IntPatch_Point ptsol;
501 ptsol.SetValue(apex,TolTang,Standard_False);
502 ptsol.SetParameters(U1,V1,U2,V2);
503 ptsol.SetParameter(para);
504 ptsol.SetMultiple(Standard_True);
505 Handle(IntPatch_GLine) glig;
506 glig = new IntPatch_GLine(linsol, Standard_False,trans1,trans2);
507 glig->AddVertex(ptsol);
508 glig->SetFirstPoint(1);
510 //-----------------------------------------------------------
511 //-- Other Side : Les transitions restent les memes
512 //-- linsol -> -linsol et Quad1(2).N -> -Quad1(2).N
514 linsol.SetDirection(linsol.Direction().Reversed());
515 glig = new IntPatch_GLine(linsol, Standard_False,trans1,trans2);
516 para = ElCLib::Parameter(linsol, apex);
517 ptsol.SetParameter(para);
518 glig->AddVertex(ptsol);
519 glig->SetFirstPoint(1);
522 //------------------------------------------- Ligne 2 -------
523 linsol = inter.Line(2);
524 if (linsol.Direction().Dot(Co.Axis().Direction()) <0.) {
525 linsol.SetDirection(linsol.Direction().Reversed());
527 para = ElCLib::Parameter(linsol, apex);
528 ptbid = ElCLib::Value(para+5.,linsol);
529 if (linsol.Direction().DotCross
530 (Quad2.Normale(ptbid),Quad1.Normale(ptbid)) >0.) {
531 trans1 = IntSurf_Out;
536 trans2 = IntSurf_Out;
538 ptsol.SetParameter(para);
539 glig = new IntPatch_GLine(linsol, Standard_False,trans1,trans2);
540 para = ElCLib::Parameter(linsol, apex);
541 ptsol.SetParameter(para);
542 glig->AddVertex(ptsol);
543 glig->SetFirstPoint(1);
545 //-----------------------------------------------------------
546 //-- Other Side : Les transitions restent les memes
547 //-- linsol -> -linsol et Quad1(2).N -> -Quad1(2).N
549 linsol.SetDirection(linsol.Direction().Reversed());
550 glig = new IntPatch_GLine(linsol, Standard_False,trans1,trans2);
551 para = ElCLib::Parameter(linsol, apex);
552 ptsol.SetParameter(para);
553 glig->AddVertex(ptsol);
554 glig->SetFirstPoint(1);
560 case IntAna_Circle: {
561 gp_Circ cirsol = inter.Circle(1);
562 //modified by NIZNHY-PKV Thu Sep 15 11:34:04 2011f
563 AdjustToSeam(Co, cirsol);
564 //modified by NIZNHY-PKV Thu Sep 15 11:36:08 2011t
567 ElCLib::D1(0.,cirsol,ptref,Tgt);
569 if (Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref)) >0.) {
570 trans1 = IntSurf_Out;
575 trans2 = IntSurf_Out;
577 Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
582 case IntAna_Ellipse: {
583 gp_Elips elipsol = inter.Ellipse(1);
586 ElCLib::D1(0.,elipsol,ptref,Tgt);
588 if (Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref)) >0.) {
589 trans1 = IntSurf_Out;
594 trans2 = IntSurf_Out;
596 Handle(IntPatch_GLine) glig = new IntPatch_GLine(elipsol,Standard_False,trans1,trans2);
601 case IntAna_Parabola: {
602 gp_Parab parabsol = inter.Parabola(1);
604 gp_Vec Tgtorig(parabsol.YAxis().Direction());
605 Standard_Real ptran = Tgtorig.DotCross(Quad2.Normale(parabsol.Location()),
606 Quad1.Normale(parabsol.Location()));
607 if (ptran >0.00000001) {
608 trans1 = IntSurf_Out;
611 else if (ptran <-0.00000001) {
613 trans2 = IntSurf_Out;
616 trans1=trans2=IntSurf_Undecided;
618 Handle(IntPatch_GLine) glig = new IntPatch_GLine(parabsol,Standard_False,trans1,trans2);
623 case IntAna_Hyperbola: {
627 for(Standard_Integer i=1; i<=2; i++) {
628 gp_Hypr hyprsol = inter.Hyperbola(i);
629 tophypr = ElCLib::Value(hyprsol.MajorRadius(),
631 Tgttop = hyprsol.YAxis().Direction();
632 Standard_Real qwe = Tgttop.DotCross(Quad2.Normale(tophypr),
633 Quad1.Normale(tophypr));
635 if (qwe>0.00000001) {
636 trans1 = IntSurf_Out;
639 else if (qwe<-0.00000001){
641 trans2 = IntSurf_Out;
644 trans1=trans2=IntSurf_Undecided;
646 Handle(IntPatch_GLine) glig = new IntPatch_GLine(hyprsol,Standard_False,trans1,trans2);
653 return Standard_False;
656 return Standard_True;
659 //modified by NIZNHY-PKV Thu Sep 15 10:53:39 2011f
660 //=======================================================================
661 //function : AdjustToSeam
663 //=======================================================================
664 void AdjustToSeam (const gp_Cone& aQuad,
669 const gp_Pnt& aPLoc=aCirc.Location();
670 const gp_Ax3& aAx3=aQuad.Position();
671 SeamPosition(aPLoc, aAx3, aAx2);
672 aCirc.SetPosition(aAx2);
674 //=======================================================================
675 //function : AdjustToSeam
677 //=======================================================================
678 void AdjustToSeam (const gp_Sphere& aQuad,
680 const Standard_Real aTolAng)
684 const gp_Ax1& aAx1C=aCirc.Axis();
685 const gp_Ax3& aAx3=aQuad.Position();
686 const gp_Ax1& aAx1Q=aAx3.Axis();
688 const gp_Dir& aDirC=aAx1C.Direction();
689 const gp_Dir& aDirQ=aAx1Q.Direction();
690 if (aDirC.IsParallel(aDirQ, aTolAng)) {
691 const gp_Pnt& aPLoc=aCirc.Location();
692 SeamPosition(aPLoc, aAx3, aAx2);
693 aCirc.SetPosition(aAx2);
696 //=======================================================================
697 //function : AdjustToSeam
699 //=======================================================================
700 void AdjustToSeam (const gp_Cylinder& aQuad,
705 const gp_Pnt& aPLoc=aCirc.Location();
706 const gp_Ax3& aAx3=aQuad.Position();
707 SeamPosition(aPLoc, aAx3, aAx2);
708 aCirc.SetPosition(aAx2);
710 //=======================================================================
711 //function : SeamPosition
713 //=======================================================================
714 void SeamPosition(const gp_Pnt& aPLoc,
718 const gp_Dir& aDZ=aPos.Direction();
719 const gp_Dir& aDX=aPos.XDirection();
720 gp_Ax2 aAx2(aPLoc, aDZ, aDX);
724 //modified by NIZNHY-PKV Thu Sep 15 10:53:41 2011t