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 <IntAna_ListOfCurve.hxx>
18 #include <IntAna_ListIteratorOfListOfCurve.hxx>
19 #include <IntPatch_WLine.hxx>
23 Standard_Boolean ExploreCurve(const gp_Cylinder& aCy,
26 const Standard_Real aTol,
27 IntAna_ListOfCurve& aLC);
29 Standard_Boolean IsToReverse(const gp_Cylinder& Cy1,
30 const gp_Cylinder& Cy2,
31 const Standard_Real Tol);
33 // ------------------------------------------------------------------
34 // MinMax : Replaces theParMIN = MIN(theParMIN, theParMAX),
35 // theParMAX = MAX(theParMIN, theParMAX).
36 // ------------------------------------------------------------------
37 static inline void MinMax(Standard_Real& theParMIN, Standard_Real& theParMAX)
39 if(theParMIN > theParMAX)
41 const Standard_Real aux = theParMAX;
42 theParMAX = theParMIN;
48 //=======================================================================
49 //function : ProcessBounds
51 //=======================================================================
52 void ProcessBounds(const Handle(IntPatch_ALine)& alig, //-- ligne courante
53 const IntPatch_SequenceOfLine& slin,
54 const IntSurf_Quadric& Quad1,
55 const IntSurf_Quadric& Quad2,
56 Standard_Boolean& procf,
57 const gp_Pnt& ptf, //-- Debut Ligne Courante
58 const Standard_Real first, //-- Paramf
59 Standard_Boolean& procl,
60 const gp_Pnt& ptl, //-- Fin Ligne courante
61 const Standard_Real last, //-- Paraml
62 Standard_Boolean& Multpoint,
63 const Standard_Real Tol)
66 Standard_Real U1,V1,U2,V2;
71 j = slin.Length() + 1;
78 //-- On prend les lignes deja enregistrees
80 while (j <= slin.Length()) {
81 if(slin.Value(j)->ArcType() == IntPatch_Analytic) {
82 const Handle(IntPatch_ALine)& aligold = *((Handle(IntPatch_ALine)*)&slin.Value(j));
85 //-- On prend les vertex des lignes deja enregistrees
87 while (k <= aligold->NbVertex()) {
88 ptsol = aligold->Vertex(k);
90 d=ptf.Distance(ptsol.Value());
92 if (!ptsol.IsMultiple()) {
93 //-- le point ptsol (de aligold) est declare multiple sur aligold
94 Multpoint = Standard_True;
95 ptsol.SetMultiple(Standard_True);
96 aligold->Replace(k,ptsol);
98 ptsol.SetParameter(first);
99 alig->AddVertex(ptsol);
100 alig->SetFirstPoint(alig->NbVertex());
101 procf = Standard_True;
103 //-- On restore le point avec son parametre sur aligold
104 ptsol = aligold->Vertex(k);
109 if (ptl.Distance(ptsol.Value()) <= Tol) {
110 if (!ptsol.IsMultiple()) {
111 Multpoint = Standard_True;
112 ptsol.SetMultiple(Standard_True);
113 aligold->Replace(k,ptsol);
115 ptsol.SetParameter(last);
116 alig->AddVertex(ptsol);
117 alig->SetLastPoint(alig->NbVertex());
118 procl = Standard_True;
120 //-- On restore le point avec son parametre sur aligold
121 ptsol = aligold->Vertex(k);
125 if (procf && procl) {
126 k = aligold->NbVertex()+1;
132 if (procf && procl) {
140 if (!procf && !procl) {
141 Quad1.Parameters(ptf,U1,V1);
142 Quad2.Parameters(ptf,U2,V2);
143 ptsol.SetValue(ptf,Tol,Standard_False);
144 ptsol.SetParameters(U1,V1,U2,V2);
145 ptsol.SetParameter(first);
146 if (ptf.Distance(ptl) <= Tol) {
147 ptsol.SetMultiple(Standard_True); // a voir
148 Multpoint = Standard_True; // a voir de meme
149 alig->AddVertex(ptsol);
150 alig->SetFirstPoint(alig->NbVertex());
152 ptsol.SetParameter(last);
153 alig->AddVertex(ptsol);
154 alig->SetLastPoint(alig->NbVertex());
157 alig->AddVertex(ptsol);
158 alig->SetFirstPoint(alig->NbVertex());
159 Quad1.Parameters(ptl,U1,V1);
160 Quad2.Parameters(ptl,U2,V2);
161 ptsol.SetValue(ptl,Tol,Standard_False);
162 ptsol.SetParameters(U1,V1,U2,V2);
163 ptsol.SetParameter(last);
164 alig->AddVertex(ptsol);
165 alig->SetLastPoint(alig->NbVertex());
169 Quad1.Parameters(ptf,U1,V1);
170 Quad2.Parameters(ptf,U2,V2);
171 ptsol.SetValue(ptf,Tol,Standard_False);
172 ptsol.SetParameters(U1,V1,U2,V2);
173 ptsol.SetParameter(first);
174 alig->AddVertex(ptsol);
175 alig->SetFirstPoint(alig->NbVertex());
178 Quad1.Parameters(ptl,U1,V1);
179 Quad2.Parameters(ptl,U2,V2);
180 ptsol.SetValue(ptl,Tol,Standard_False);
181 ptsol.SetParameters(U1,V1,U2,V2);
182 ptsol.SetParameter(last);
183 alig->AddVertex(ptsol);
184 alig->SetLastPoint(alig->NbVertex());
187 //=======================================================================
190 //=======================================================================
191 Standard_Boolean IntCyCy(const IntSurf_Quadric& Quad1,
192 const IntSurf_Quadric& Quad2,
193 const Standard_Real Tol,
194 Standard_Boolean& Empty,
195 Standard_Boolean& Same,
196 Standard_Boolean& Multpoint,
197 IntPatch_SequenceOfLine& slin,
198 IntPatch_SequenceOfPoint& spnt)
201 IntPatch_Point ptsol;
205 IntSurf_TypeTrans trans1,trans2;
206 IntAna_ResultType typint;
211 gp_Cylinder Cy1(Quad1.Cylinder());
212 gp_Cylinder Cy2(Quad2.Cylinder());
214 IntAna_QuadQuadGeo inter(Cy1,Cy2,Tol);
218 return Standard_False;
221 typint = inter.TypeInter();
222 Standard_Integer NbSol = inter.NbSolutions();
223 Empty = Standard_False;
224 Same = Standard_False;
230 Empty = Standard_True;
236 Same = Standard_True;
242 gp_Pnt psol(inter.Point(1));
243 Standard_Real U1,V1,U2,V2;
244 Quad1.Parameters(psol,U1,V1);
245 Quad2.Parameters(psol,U2,V2);
246 ptsol.SetValue(psol,Tol,Standard_True);
247 ptsol.SetParameters(U1,V1,U2,V2);
256 { // Cylinders are tangent to each other by line
257 linsol = inter.Line(1);
258 ptref = linsol.Location();
259 gp_Dir crb1(gp_Vec(ptref,Cy1.Location()));
260 gp_Dir crb2(gp_Vec(ptref,Cy2.Location()));
261 gp_Vec norm1(Quad1.Normale(ptref));
262 gp_Vec norm2(Quad2.Normale(ptref));
263 IntSurf_Situation situcyl1;
264 IntSurf_Situation situcyl2;
266 if (crb1.Dot(crb2) < 0.)
267 { // centre de courbures "opposes"
268 if (norm1.Dot(crb1) > 0.)
270 situcyl2 = IntSurf_Inside;
274 situcyl2 = IntSurf_Outside;
277 if (norm2.Dot(crb2) > 0.)
279 situcyl1 = IntSurf_Inside;
283 situcyl1 = IntSurf_Outside;
288 if (Cy1.Radius() < Cy2.Radius())
290 if (norm1.Dot(crb1) > 0.)
292 situcyl2 = IntSurf_Inside;
296 situcyl2 = IntSurf_Outside;
299 if (norm2.Dot(crb2) > 0.)
301 situcyl1 = IntSurf_Outside;
305 situcyl1 = IntSurf_Inside;
310 if (norm1.Dot(crb1) > 0.)
312 situcyl2 = IntSurf_Outside;
316 situcyl2 = IntSurf_Inside;
319 if (norm2.Dot(crb2) > 0.)
321 situcyl1 = IntSurf_Inside;
325 situcyl1 = IntSurf_Outside;
330 Handle(IntPatch_GLine) glig = new IntPatch_GLine(linsol, Standard_True, situcyl1, situcyl2);
335 for (i=1; i <= NbSol; i++)
337 linsol = inter.Line(i);
338 ptref = linsol.Location();
339 gp_Vec lsd = linsol.Direction();
340 Standard_Real qwe = lsd.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
343 trans1 = IntSurf_Out;
346 else if (qwe <-0.00000001)
349 trans2 = IntSurf_Out;
353 trans1=trans2=IntSurf_Undecided;
356 Handle(IntPatch_GLine) glig = new IntPatch_GLine(linsol, Standard_False,trans1,trans2);
367 IntPatch_Point pmult1, pmult2;
369 elipsol = inter.Ellipse(1);
371 gp_Pnt pttang1(ElCLib::Value(0.5*M_PI, elipsol));
372 gp_Pnt pttang2(ElCLib::Value(1.5*M_PI, elipsol));
374 Multpoint = Standard_True;
375 pmult1.SetValue(pttang1,Tol,Standard_True);
376 pmult2.SetValue(pttang2,Tol,Standard_True);
377 pmult1.SetMultiple(Standard_True);
378 pmult2.SetMultiple(Standard_True);
380 Standard_Real oU1,oV1,oU2,oV2;
381 Quad1.Parameters(pttang1,oU1,oV1);
382 Quad2.Parameters(pttang1,oU2,oV2);
383 pmult1.SetParameters(oU1,oV1,oU2,oV2);
385 Quad1.Parameters(pttang2,oU1,oV1);
386 Quad2.Parameters(pttang2,oU2,oV2);
387 pmult2.SetParameters(oU1,oV1,oU2,oV2);
389 // on traite la premiere ellipse
391 //-- Calcul de la Transition de la ligne
392 ElCLib::D1(0.,elipsol,ptref,Tgt);
393 Standard_Real qwe=Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
396 trans1 = IntSurf_Out;
399 else if (qwe<-0.00000001)
402 trans2 = IntSurf_Out;
406 trans1=trans2=IntSurf_Undecided;
409 //-- Transition calculee au point 0 -> Trans2 , Trans1
410 //-- car ici, on devarit calculer en PI
411 Handle(IntPatch_GLine) glig = new IntPatch_GLine(elipsol,Standard_False,trans2,trans1);
414 Standard_Real aU1, aV1, aU2, aV2;
416 gp_Pnt aP (ElCLib::Value(0., elipsol));
418 aIP.SetValue(aP,Tol,Standard_False);
419 aIP.SetMultiple(Standard_False);
421 Quad1.Parameters(aP, aU1, aV1);
422 Quad2.Parameters(aP, aU2, aV2);
423 aIP.SetParameters(aU1, aV1, aU2, aV2);
425 aIP.SetParameter(0.);
426 glig->AddVertex(aIP);
427 glig->SetFirstPoint(1);
429 aIP.SetParameter(2.*M_PI);
430 glig->AddVertex(aIP);
431 glig->SetLastPoint(2);
434 pmult1.SetParameter(0.5*M_PI);
435 glig->AddVertex(pmult1);
437 pmult2.SetParameter(1.5*M_PI);
438 glig->AddVertex(pmult2);
443 //-- Transitions calculee au point 0 OK
445 // on traite la deuxieme ellipse
446 elipsol = inter.Ellipse(2);
448 Standard_Real param1 = ElCLib::Parameter(elipsol,pttang1);
449 Standard_Real param2 = ElCLib::Parameter(elipsol,pttang2);
450 Standard_Real parampourtransition = 0.0;
453 pmult1.SetParameter(0.5*M_PI);
454 pmult2.SetParameter(1.5*M_PI);
455 parampourtransition = M_PI;
458 pmult1.SetParameter(1.5*M_PI);
459 pmult2.SetParameter(0.5*M_PI);
460 parampourtransition = 0.0;
463 //-- Calcul des transitions de ligne pour la premiere ligne
464 ElCLib::D1(parampourtransition,elipsol,ptref,Tgt);
465 qwe=Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
468 trans1 = IntSurf_Out;
471 else if(qwe< -0.00000001)
474 trans2 = IntSurf_Out;
478 trans1=trans2=IntSurf_Undecided;
481 //-- La transition a ete calculee sur un point de cette ligne
482 glig = new IntPatch_GLine(elipsol,Standard_False,trans1,trans2);
485 Standard_Real aU1, aV1, aU2, aV2;
487 gp_Pnt aP (ElCLib::Value(0., elipsol));
489 aIP.SetValue(aP,Tol,Standard_False);
490 aIP.SetMultiple(Standard_False);
492 Quad1.Parameters(aP, aU1, aV1);
493 Quad2.Parameters(aP, aU2, aV2);
494 aIP.SetParameters(aU1, aV1, aU2, aV2);
496 aIP.SetParameter(0.);
497 glig->AddVertex(aIP);
498 glig->SetFirstPoint(1);
500 aIP.SetParameter(2.*M_PI);
501 glig->AddVertex(aIP);
502 glig->SetLastPoint(2);
505 glig->AddVertex(pmult1);
506 glig->AddVertex(pmult2);
512 case IntAna_NoGeometricSolution:
514 Standard_Boolean bReverse;
515 Standard_Real U1,V1,U2,V2;
518 bReverse=IsToReverse(Cy1, Cy2, Tol);
521 Cy2=Quad1.Cylinder();
522 Cy1=Quad2.Cylinder();
525 IntAna_IntQuadQuad anaint(Cy1,Cy2,Tol);
526 if (!anaint.IsDone())
528 return Standard_False;
531 if (anaint.NbPnt() == 0 && anaint.NbCurve() == 0)
533 Empty = Standard_True;
537 NbSol = anaint.NbPnt();
538 for (i = 1; i <= NbSol; i++)
540 psol = anaint.Point(i);
541 Quad1.Parameters(psol,U1,V1);
542 Quad2.Parameters(psol,U2,V2);
543 ptsol.SetValue(psol,Tol,Standard_True);
544 ptsol.SetParameters(U1,V1,U2,V2);
548 gp_Pnt ptvalid, ptf, ptl;
551 Standard_Real first,last,para;
552 IntAna_Curve curvsol;
553 Standard_Boolean tgfound;
554 Standard_Integer kount;
556 NbSol = anaint.NbCurve();
557 for (i = 1; i <= NbSol; i++)
559 curvsol = anaint.Curve(i);
560 curvsol.Domain(first,last);
561 ptf = curvsol.Value(first);
562 ptl = curvsol.Value(last);
566 tgfound = Standard_False;
570 para = (1.123*first + para)/2.123;
571 tgfound = curvsol.D1u(para,ptvalid,tgvalid);
579 Handle(IntPatch_ALine) alig;
582 Standard_Real qwe = tgvalid.DotCross( Quad2.Normale(ptvalid),
583 Quad1.Normale(ptvalid));
586 trans1 = IntSurf_Out;
589 else if(qwe<-0.00000001)
592 trans2 = IntSurf_Out;
596 trans1=trans2=IntSurf_Undecided;
598 alig = new IntPatch_ALine(curvsol,Standard_False,trans1,trans2);
602 alig = new IntPatch_ALine(curvsol,Standard_False);
603 //-- cout << "Transition indeterminee" << endl;
606 Standard_Boolean TempFalse1 = Standard_False;
607 Standard_Boolean TempFalse2 = Standard_False;
609 ProcessBounds(alig,slin,Quad1,Quad2,TempFalse1,ptf,first,
610 TempFalse2,ptl,last,Multpoint,Tol);
618 return Standard_False;
621 return Standard_True;
624 //=======================================================================
625 //function : ShortCosForm
626 //purpose : Represents theCosFactor*cosA+theSinFactor*sinA as
627 // theCoeff*cos(A-theAngle) if it is possibly (all angles are
629 //=======================================================================
630 static void ShortCosForm( const Standard_Real theCosFactor,
631 const Standard_Real theSinFactor,
632 Standard_Real& theCoeff,
633 Standard_Real& theAngle)
635 theCoeff = sqrt(theCosFactor*theCosFactor+theSinFactor*theSinFactor);
637 if(IsEqual(theCoeff, 0.0))
643 theAngle = acos(Abs(theCosFactor/theCoeff));
645 if(theSinFactor > 0.0)
647 if(IsEqual(theCosFactor, 0.0))
651 else if(theCosFactor < 0.0)
653 theAngle = M_PI-theAngle;
656 else if(IsEqual(theSinFactor, 0.0))
658 if(theCosFactor < 0.0)
663 if(theSinFactor < 0.0)
665 if(theCosFactor > 0.0)
667 theAngle = 2.0*M_PI-theAngle;
669 else if(IsEqual(theCosFactor, 0.0))
671 theAngle = 3.0*M_PI/2.0;
673 else if(theCosFactor < 0.0)
675 theAngle = M_PI+theAngle;
687 //Stores equations coefficients
690 stCoeffsValue(const gp_Cylinder&, const gp_Cylinder&);
700 Standard_Real mK21; //sinU2
701 Standard_Real mK11; //sinU1
702 Standard_Real mL21; //cosU2
703 Standard_Real mL11; //cosU1
704 Standard_Real mM1; //Free member
706 Standard_Real mK22; //sinU2
707 Standard_Real mK12; //sinU1
708 Standard_Real mL22; //cosU2
709 Standard_Real mL12; //cosU1
710 Standard_Real mM2; //Free member
718 Standard_Real mPSIV1;
720 Standard_Real mPSIV2;
728 stCoeffsValue::stCoeffsValue( const gp_Cylinder& theCyl1,
729 const gp_Cylinder& theCyl2)
731 const Standard_Real aNulValue = 0.01*Precision::PConfusion();
733 mVecA1 = -theCyl1.Radius()*theCyl1.XAxis().Direction();
734 mVecA2 = theCyl2.Radius()*theCyl2.XAxis().Direction();
736 mVecB1 = -theCyl1.Radius()*theCyl1.YAxis().Direction();
737 mVecB2 = theCyl2.Radius()*theCyl2.YAxis().Direction();
739 mVecC1 = theCyl1.Axis().Direction();
740 mVecC2 = -(theCyl2.Axis().Direction());
742 mVecD = theCyl2.Location().XYZ() - theCyl1.Location().XYZ();
744 enum CoupleOfEquation
750 }aFoundCouple = COENONE;
753 Standard_Real aDetV1V2 = mVecC1.X()*mVecC2.Y()-mVecC1.Y()*mVecC2.X();
755 if(Abs(aDetV1V2) < aNulValue)
757 aDetV1V2 = mVecC1.Y()*mVecC2.Z()-mVecC1.Z()*mVecC2.Y();
758 if(Abs(aDetV1V2) < aNulValue)
760 aDetV1V2 = mVecC1.X()*mVecC2.Z()-mVecC1.Z()*mVecC2.X();
761 if(Abs(aDetV1V2) < aNulValue)
763 Standard_Failure::Raise("Error. Exception in divide by zerro (IntCyCyTrim)!!!!");
767 aFoundCouple = COE13;
772 aFoundCouple = COE23;
777 aFoundCouple = COE12;
786 gp_Vec aVTemp = mVecA1;
787 mVecA1.SetX(aVTemp.Y());
788 mVecA1.SetY(aVTemp.Z());
789 mVecA1.SetZ(aVTemp.X());
792 mVecA2.SetX(aVTemp.Y());
793 mVecA2.SetY(aVTemp.Z());
794 mVecA2.SetZ(aVTemp.X());
797 mVecB1.SetX(aVTemp.Y());
798 mVecB1.SetY(aVTemp.Z());
799 mVecB1.SetZ(aVTemp.X());
802 mVecB2.SetX(aVTemp.Y());
803 mVecB2.SetY(aVTemp.Z());
804 mVecB2.SetZ(aVTemp.X());
807 mVecC1.SetX(aVTemp.Y());
808 mVecC1.SetY(aVTemp.Z());
809 mVecC1.SetZ(aVTemp.X());
812 mVecC2.SetX(aVTemp.Y());
813 mVecC2.SetY(aVTemp.Z());
814 mVecC2.SetZ(aVTemp.X());
817 mVecD.SetX(aVTemp.Y());
818 mVecD.SetY(aVTemp.Z());
819 mVecD.SetZ(aVTemp.X());
825 gp_Vec aVTemp = mVecA1;
826 mVecA1.SetY(aVTemp.Z());
827 mVecA1.SetZ(aVTemp.Y());
830 mVecA2.SetY(aVTemp.Z());
831 mVecA2.SetZ(aVTemp.Y());
834 mVecB1.SetY(aVTemp.Z());
835 mVecB1.SetZ(aVTemp.Y());
838 mVecB2.SetY(aVTemp.Z());
839 mVecB2.SetZ(aVTemp.Y());
842 mVecC1.SetY(aVTemp.Z());
843 mVecC1.SetZ(aVTemp.Y());
846 mVecC2.SetY(aVTemp.Z());
847 mVecC2.SetZ(aVTemp.Y());
850 mVecD.SetY(aVTemp.Z());
851 mVecD.SetZ(aVTemp.Y());
859 //------- For V1 (begin)
861 mK21 = (mVecC2.Y()*mVecB2.X()-mVecC2.X()*mVecB2.Y())/aDetV1V2;
863 mK11 = (mVecC2.Y()*mVecB1.X()-mVecC2.X()*mVecB1.Y())/aDetV1V2;
865 mL21 = (mVecC2.Y()*mVecA2.X()-mVecC2.X()*mVecA2.Y())/aDetV1V2;
867 mL11 = (mVecC2.Y()*mVecA1.X()-mVecC2.X()*mVecA1.Y())/aDetV1V2;
869 mM1 = (mVecC2.Y()*mVecD.X()-mVecC2.X()*mVecD.Y())/aDetV1V2;
870 //------- For V1 (end)
872 //------- For V2 (begin)
874 mK22 = (mVecC1.X()*mVecB2.Y()-mVecC1.Y()*mVecB2.X())/aDetV1V2;
876 mK12 = (mVecC1.X()*mVecB1.Y()-mVecC1.Y()*mVecB1.X())/aDetV1V2;
878 mL22 = (mVecC1.X()*mVecA2.Y()-mVecC1.Y()*mVecA2.X())/aDetV1V2;
880 mL12 = (mVecC1.X()*mVecA1.Y()-mVecC1.Y()*mVecA1.X())/aDetV1V2;
882 mM2 = (mVecC1.X()*mVecD.Y()-mVecC1.Y()*mVecD.X())/aDetV1V2;
883 //------- For V1 (end)
885 ShortCosForm(mL11, mK11, mK1, mFIV1);
886 ShortCosForm(mL21, mK21, mL1, mPSIV1);
887 ShortCosForm(mL12, mK12, mK2, mFIV2);
888 ShortCosForm(mL22, mK22, mL2, mPSIV2);
890 const Standard_Real aA1=mVecC1.Z()*mK21+mVecC2.Z()*mK22-mVecB2.Z(), //sinU2
891 aA2=mVecC1.Z()*mL21+mVecC2.Z()*mL22-mVecA2.Z(), //cosU2
892 aB1=mVecB1.Z()-mVecC1.Z()*mK11-mVecC2.Z()*mK12, //sinU1
893 aB2=mVecA1.Z()-mVecC1.Z()*mL11-mVecC2.Z()*mL12; //cosU1
895 mC =mVecD.Z() -mVecC1.Z()*mM1 -mVecC2.Z()*mM2; //Free
897 Standard_Real aA = 0.0;
899 ShortCosForm(aB2,aB1,mB,mFI1);
900 ShortCosForm(aA2,aA1,aA,mFI2);
906 //=======================================================================
907 //function : SearchOnVBounds
909 //=======================================================================
910 static Standard_Boolean SearchOnVBounds(const SearchBoundType theSBType,
911 const stCoeffsValue& theCoeffs,
912 const Standard_Real theVzad,
913 const Standard_Real theInitU2,
914 const Standard_Real theInitMainVar,
915 Standard_Real& theMainVariableValue)
917 const Standard_Real aMaxError = 4.0*M_PI; // two periods
919 theMainVariableValue = RealLast();
920 const Standard_Real aTol2 = Precision::PConfusion()*Precision::PConfusion();
921 Standard_Real aMainVarPrev = theInitMainVar, aU2Prev = theInitU2, anOtherVar = theVzad;
923 Standard_Real anError = RealLast();
924 Standard_Integer aNbIter = 0;
928 return Standard_False;
930 gp_Vec aVecMainVar = theCoeffs.mVecA1 * sin(aMainVarPrev) - theCoeffs.mVecB1 * cos(aMainVarPrev);
931 gp_Vec aVecFreeMem = (theCoeffs.mVecA2 * aU2Prev + theCoeffs.mVecB2) * sin(aU2Prev) -
932 (theCoeffs.mVecB2 * aU2Prev - theCoeffs.mVecA2) * cos(aU2Prev) +
933 (theCoeffs.mVecA1 * aMainVarPrev + theCoeffs.mVecB1) * sin(aMainVarPrev) -
934 (theCoeffs.mVecB1 * aMainVarPrev - theCoeffs.mVecA1) * cos(aMainVarPrev) + theCoeffs.mVecD;
936 gp_Vec aVecVar1 = theCoeffs.mVecA2 * sin(aU2Prev) - theCoeffs.mVecB2 * cos(aU2Prev);
942 aVecVar2 = theCoeffs.mVecC2;
943 aVecFreeMem -= theCoeffs.mVecC1 * theVzad;
947 aVecVar2 = theCoeffs.mVecC1;
948 aVecFreeMem -= theCoeffs.mVecC2 * theVzad;
952 return Standard_False;
955 Standard_Real aDetMainSyst = aVecMainVar.X()*(aVecVar1.Y()*aVecVar2.Z()-aVecVar1.Z()*aVecVar2.Y())-
956 aVecMainVar.Y()*(aVecVar1.X()*aVecVar2.Z()-aVecVar1.Z()*aVecVar2.X())+
957 aVecMainVar.Z()*(aVecVar1.X()*aVecVar2.Y()-aVecVar1.Y()*aVecVar2.X());
959 if(IsEqual(aDetMainSyst, 0.0))
961 return Standard_False;
965 Standard_Real aDetMainVar = aVecFreeMem.X()*(aVecVar1.Y()*aVecVar2.Z()-aVecVar1.Z()*aVecVar2.Y())-
966 aVecFreeMem.Y()*(aVecVar1.X()*aVecVar2.Z()-aVecVar1.Z()*aVecVar2.X())+
967 aVecFreeMem.Z()*(aVecVar1.X()*aVecVar2.Y()-aVecVar1.Y()*aVecVar2.X());
969 Standard_Real aDetVar1 = aVecMainVar.X()*(aVecFreeMem.Y()*aVecVar2.Z()-aVecFreeMem.Z()*aVecVar2.Y())-
970 aVecMainVar.Y()*(aVecFreeMem.X()*aVecVar2.Z()-aVecFreeMem.Z()*aVecVar2.X())+
971 aVecMainVar.Z()*(aVecFreeMem.X()*aVecVar2.Y()-aVecFreeMem.Y()*aVecVar2.X());
973 Standard_Real aDetVar2 = aVecMainVar.X()*(aVecVar1.Y()*aVecFreeMem.Z()-aVecVar1.Z()*aVecFreeMem.Y())-
974 aVecMainVar.Y()*(aVecVar1.X()*aVecFreeMem.Z()-aVecVar1.Z()*aVecFreeMem.X())+
975 aVecMainVar.Z()*(aVecVar1.X()*aVecFreeMem.Y()-aVecVar1.Y()*aVecFreeMem.X());
977 Standard_Real aDelta = aDetMainVar/aDetMainSyst-aMainVarPrev;
979 if(Abs(aDelta) > aMaxError)
980 return Standard_False;
982 anError = aDelta*aDelta;
983 aMainVarPrev += aDelta;
986 aDelta = aDetVar1/aDetMainSyst-aU2Prev;
988 if(Abs(aDelta) > aMaxError)
989 return Standard_False;
991 anError += aDelta*aDelta;
995 aDelta = aDetVar2/aDetMainSyst-anOtherVar;
996 anError += aDelta*aDelta;
997 anOtherVar += aDelta;
999 while(anError > aTol2);
1001 theMainVariableValue = aMainVarPrev;
1003 return Standard_True;
1006 //=======================================================================
1007 //function : InscribePoint
1008 //purpose : If theFlForce==TRUE theUGiven will be adjasted forceful.
1009 //=======================================================================
1010 static Standard_Boolean InscribePoint(const Standard_Real theUfTarget,
1011 const Standard_Real theUlTarget,
1012 Standard_Real& theUGiven,
1013 const Standard_Real theTol2D,
1014 const Standard_Real thePeriod,
1015 const Standard_Boolean theFlForce)
1017 if((theUfTarget - theUGiven <= theTol2D) &&
1018 (theUGiven - theUlTarget <= theTol2D))
1019 {//it has already inscribed
1028 Standard_Real anUtemp = theUGiven + thePeriod;
1029 if((theUfTarget - anUtemp <= theTol2D) &&
1030 (anUtemp - theUlTarget <= theTol2D))
1032 theUGiven = anUtemp;
1033 return Standard_True;
1036 anUtemp = theUGiven - thePeriod;
1037 if((theUfTarget - anUtemp <= theTol2D) &&
1038 (anUtemp - theUlTarget <= theTol2D))
1040 theUGiven = anUtemp;
1044 return Standard_True;
1047 if(IsEqual(thePeriod, 0.0))
1048 {//it cannot be inscribed
1049 return Standard_False;
1052 Standard_Real aDU = theUGiven - theUfTarget;
1059 while(((theUGiven - theUfTarget)*aDU < 0.0) && !((theUfTarget - theUGiven <= theTol2D) && (theUGiven - theUlTarget <= theTol2D)))
1064 return ((theUfTarget - theUGiven <= theTol2D) && (theUGiven - theUlTarget <= theTol2D));
1067 //=======================================================================
1068 //function : InscribeInterval
1069 //purpose : Adjusts theUfGiven and after that fits theUlGiven to result
1070 //=======================================================================
1071 static Standard_Boolean InscribeInterval(const Standard_Real theUfTarget,
1072 const Standard_Real theUlTarget,
1073 Standard_Real& theUfGiven,
1074 Standard_Real& theUlGiven,
1075 const Standard_Real theTol2D,
1076 const Standard_Real thePeriod)
1078 Standard_Real anUpar = theUfGiven;
1079 const Standard_Real aDelta = theUlGiven - theUfGiven;
1080 if(InscribePoint(theUfTarget, theUlTarget, anUpar,
1081 theTol2D, thePeriod, Standard_False))
1083 theUfGiven = anUpar;
1084 theUlGiven = theUfGiven + aDelta;
1088 anUpar = theUlGiven;
1089 if(InscribePoint(theUfTarget, theUlTarget, anUpar,
1090 theTol2D, thePeriod, Standard_False))
1092 theUlGiven = anUpar;
1093 theUfGiven = theUlGiven - aDelta;
1097 return Standard_False;
1101 return Standard_True;
1104 //=======================================================================
1105 //function : InscribeAndSortArray
1106 //purpose : Sort from Min to Max value
1107 //=======================================================================
1108 static void InscribeAndSortArray( Standard_Real theArr[],
1109 const Standard_Integer theNOfMembers,
1110 const Standard_Real theUf,
1111 const Standard_Real theUl,
1112 const Standard_Real theTol2D,
1113 const Standard_Real thePeriod)
1115 for(Standard_Integer i = 0; i < theNOfMembers; i++)
1117 if(Precision::IsInfinite(theArr[i]))
1120 theArr[i] = -theArr[i];
1125 InscribePoint(theUf, theUl, theArr[i], theTol2D, thePeriod, Standard_False);
1127 for(Standard_Integer j = i - 1; j >= 0; j--)
1130 if(theArr[j+1] < theArr[j])
1132 Standard_Real anUtemp = theArr[j+1];
1133 theArr[j+1] = theArr[j];
1134 theArr[j] = anUtemp;
1141 //=======================================================================
1142 //function : AddPointIntoWL
1143 //purpose : Surf1 is a surface, whose U-par is variable.
1144 //=======================================================================
1145 static Standard_Boolean AddPointIntoWL( const IntSurf_Quadric& theQuad1,
1146 const IntSurf_Quadric& theQuad2,
1147 const Standard_Boolean isTheReverse,
1148 const gp_Pnt2d& thePntOnSurf1,
1149 const gp_Pnt2d& thePntOnSurf2,
1150 const Standard_Real theUfSurf1,
1151 const Standard_Real theUlSurf1,
1152 const Standard_Real thePeriodOfSurf1,
1153 const Handle(IntSurf_LineOn2S)& theLine,
1154 const Standard_Real theTol3D,
1155 const Standard_Real theTol2D,
1156 const Standard_Boolean theFlForce)
1158 gp_Pnt aPt1(theQuad1.Value(thePntOnSurf1.X(), thePntOnSurf1.Y())),
1159 aPt2(theQuad2.Value(thePntOnSurf2.X(), thePntOnSurf2.Y()));
1161 Standard_Real anUpar = thePntOnSurf1.X();
1162 if(!InscribePoint(theUfSurf1, theUlSurf1, anUpar, theTol2D,
1163 thePeriodOfSurf1, theFlForce))
1164 return Standard_False;
1166 IntSurf_PntOn2S aPnt;
1170 aPnt.SetValue((aPt1.XYZ()+aPt2.XYZ())/2.0,
1171 thePntOnSurf2.X(), thePntOnSurf2.Y(),
1172 anUpar, thePntOnSurf1.Y());
1176 aPnt.SetValue((aPt1.XYZ()+aPt2.XYZ())/2.0,
1177 anUpar, thePntOnSurf1.Y(),
1178 thePntOnSurf2.X(), thePntOnSurf2.Y());
1181 const Standard_Integer aNbPnts = theLine->NbPoints();
1184 Standard_Real aUl = 0.0, aVl = 0.0;
1185 const IntSurf_PntOn2S aPlast = theLine->Value(aNbPnts);
1187 aPlast.ParametersOnS2(aUl, aVl);
1189 aPlast.ParametersOnS1(aUl, aVl);
1192 {//Parameter value will be always increased.
1193 return Standard_False;
1196 //theTol2D is minimal step along parameter changed.
1197 //Therefore, if we apply this minimal step two
1198 //neighbour points will be always "same". Consequently,
1199 //we should reduce tolerance for IsSame checking.
1200 const Standard_Real aDTol = 1.0-Epsilon(1.0);
1201 if(aPnt.IsSame(aPlast, theTol3D*aDTol, theTol2D*aDTol))
1203 theLine->RemovePoint(aNbPnts);
1208 return Standard_True;
1211 //=======================================================================
1212 //function : AddBoundaryPoint
1214 //=======================================================================
1215 static Standard_Boolean AddBoundaryPoint( const IntSurf_Quadric& theQuad1,
1216 const IntSurf_Quadric& theQuad2,
1217 const Handle(IntPatch_WLine)& theWL,
1218 const stCoeffsValue& theCoeffs,
1219 const Bnd_Box2d& theUVSurf1,
1220 const Bnd_Box2d& theUVSurf2,
1221 const Standard_Real theTol3D,
1222 const Standard_Real theTol2D,
1223 const Standard_Real thePeriod,
1224 const Standard_Real theNulValue,
1225 const Standard_Real theU1,
1226 const Standard_Real theU2,
1227 const Standard_Real theV1,
1228 const Standard_Real theV1Prev,
1229 const Standard_Real theV2,
1230 const Standard_Real theV2Prev,
1231 const Standard_Boolean isTheReverse,
1232 const Standard_Real theArccosFactor,
1233 const Standard_Boolean theFlForce,
1234 Standard_Boolean& isTheFound1,
1235 Standard_Boolean& isTheFound2)
1237 Standard_Real aUSurf1f = 0.0, //const
1241 Standard_Real aUSurf2f = 0.0, //const
1246 theUVSurf1.Get(aUSurf1f, aVSurf1f, aUSurf1l, aVSurf1l);
1247 theUVSurf2.Get(aUSurf2f, aVSurf2f, aUSurf2l, aVSurf2l);
1249 SearchBoundType aTS1 = SearchNONE, aTS2 = SearchNONE;
1250 Standard_Real aV1zad = aVSurf1f, aV2zad = aVSurf2f;
1252 Standard_Real anUpar1 = theU1, anUpar2 = theU1;
1253 Standard_Real aVf = theV1, aVl = theV1Prev;
1255 if((aVf <= aVSurf1f) && (aVSurf1f <= aVl))
1259 isTheFound1 = SearchOnVBounds(aTS1, theCoeffs, aVSurf1f, theU2, theU1, anUpar1);
1261 else if((aVf <= aVSurf1l) && (aVSurf1l <= aVl))
1265 isTheFound1 = SearchOnVBounds(aTS1, theCoeffs, aVSurf1l, theU2, theU1, anUpar1);
1272 if((aVf <= aVSurf2f) && (aVSurf2f <= aVl))
1276 isTheFound2 = SearchOnVBounds(aTS2, theCoeffs, aVSurf2f, theU2, theU1, anUpar2);
1278 else if((aVf <= aVSurf2l) && (aVSurf2l <= aVl))
1282 isTheFound2 = SearchOnVBounds(aTS2, theCoeffs, aVSurf2l, theU2, theU1, anUpar2);
1285 if(anUpar1 < anUpar2)
1289 Standard_Real anArg = theCoeffs.mB * cos(anUpar1 - theCoeffs.mFI1) + theCoeffs.mC;
1291 if(theNulValue > 1.0 - anArg)
1293 if(anArg + 1.0 < theNulValue)
1296 Standard_Real aU2 = theCoeffs.mFI2 + theArccosFactor * acos(anArg);
1298 if(InscribePoint(aUSurf2f, aUSurf2l, aU2, theTol2D, thePeriod, Standard_False))
1300 const Standard_Real aV1 =
1301 (aTS1 == SearchV1) ? aV1zad :
1302 theCoeffs.mK21 * sin(aU2) + theCoeffs.mK11 * sin(anUpar1) +
1303 theCoeffs.mL21 * cos(aU2) + theCoeffs.mL11 * cos(anUpar1) + theCoeffs.mM1;
1304 const Standard_Real aV2 =
1305 (aTS1 == SearchV2) ? aV2zad :
1306 theCoeffs.mK22 * sin(aU2) + theCoeffs.mK12 * sin(anUpar1) +
1307 theCoeffs.mL22 * cos(aU2) + theCoeffs.mL12 * cos(anUpar1) + theCoeffs.mM2;
1309 AddPointIntoWL(theQuad1, theQuad2, isTheReverse,
1310 gp_Pnt2d(anUpar1, aV1), gp_Pnt2d(aU2, aV2),
1311 aUSurf1f, aUSurf1l, thePeriod,
1312 theWL->Curve(), theTol3D, theTol2D, theFlForce);
1316 isTheFound1 = Standard_False;
1322 Standard_Real anArg = theCoeffs.mB * cos(anUpar2 - theCoeffs.mFI1) + theCoeffs.mC;
1324 if(theNulValue > 1.0 - anArg)
1326 if(anArg + 1.0 < theNulValue)
1329 Standard_Real aU2 = theCoeffs.mFI2 + theArccosFactor * acos(anArg);
1330 if(InscribePoint(aUSurf2f, aUSurf2l, aU2, theTol2D, thePeriod, Standard_False))
1332 const Standard_Real aV1 =
1333 (aTS2 == SearchV1) ? aV1zad :
1334 theCoeffs.mK21 * sin(aU2) + theCoeffs.mK11 * sin(anUpar2) +
1335 theCoeffs.mL21 * cos(aU2) + theCoeffs.mL11 * cos(anUpar2) + theCoeffs.mM1;
1336 const Standard_Real aV2 =
1337 (aTS2 == SearchV2) ? aV2zad :
1338 theCoeffs.mK22 * sin(aU2) + theCoeffs.mK12 * sin(anUpar2) +
1339 theCoeffs.mL22 * cos(aU2) + theCoeffs.mL12 * cos(anUpar2) + theCoeffs.mM2;
1341 AddPointIntoWL(theQuad1, theQuad2, isTheReverse,
1342 gp_Pnt2d(anUpar2, aV1), gp_Pnt2d(aU2, aV2),
1343 aUSurf1f, aUSurf1l, thePeriod,
1344 theWL->Curve(),theTol3D, theTol2D, theFlForce);
1348 isTheFound2 = Standard_False;
1356 Standard_Real anArg = theCoeffs.mB * cos(anUpar2 - theCoeffs.mFI1) + theCoeffs.mC;
1358 if(theNulValue > 1.0 - anArg)
1360 if(anArg + 1.0 < theNulValue)
1363 Standard_Real aU2 = theCoeffs.mFI2 + theArccosFactor * acos(anArg);
1365 if(InscribePoint(aUSurf2f, aUSurf2l, aU2, theTol2D, thePeriod, Standard_False))
1367 const Standard_Real aV1 = (aTS2 == SearchV1) ? aV1zad :
1368 theCoeffs.mK21 * sin(aU2) + theCoeffs.mK11 * sin(anUpar2) +
1369 theCoeffs.mL21 * cos(aU2) + theCoeffs.mL11 * cos(anUpar2) + theCoeffs.mM1;
1370 const Standard_Real aV2 = (aTS2 == SearchV2) ? aV2zad :
1371 theCoeffs.mK22 * sin(aU2) + theCoeffs.mK12 * sin(anUpar2) +
1372 theCoeffs.mL22 * cos(aU2) + theCoeffs.mL12 * cos(anUpar2) + theCoeffs.mM2;
1374 AddPointIntoWL(theQuad1, theQuad2, isTheReverse,
1375 gp_Pnt2d(anUpar2, aV1), gp_Pnt2d(aU2, aV2),
1376 aUSurf1f, aUSurf1l, thePeriod,
1377 theWL->Curve(), theTol3D, theTol2D, theFlForce);
1381 isTheFound2 = Standard_False;
1387 Standard_Real anArg = theCoeffs.mB*cos(anUpar1-theCoeffs.mFI1)+theCoeffs.mC;
1389 if(theNulValue > 1.0 - anArg)
1391 if(anArg + 1.0 < theNulValue)
1394 Standard_Real aU2 = theCoeffs.mFI2+theArccosFactor*acos(anArg);
1395 if(InscribePoint(aUSurf2f, aUSurf2l, aU2, theTol2D, thePeriod, Standard_False))
1397 const Standard_Real aV1 = (aTS1 == SearchV1) ? aV1zad :
1398 theCoeffs.mK21 * sin(aU2) + theCoeffs.mK11 * sin(anUpar1) +
1399 theCoeffs.mL21 * cos(aU2) + theCoeffs.mL11 * cos(anUpar1) + theCoeffs.mM1;
1400 const Standard_Real aV2 = (aTS1 == SearchV2) ? aV2zad :
1401 theCoeffs.mK22 * sin(aU2) + theCoeffs.mK12 * sin(anUpar1) +
1402 theCoeffs.mL22 * cos(aU2) + theCoeffs.mL12 * cos(anUpar1) + theCoeffs.mM2;
1404 AddPointIntoWL(theQuad1, theQuad2, isTheReverse,
1405 gp_Pnt2d(anUpar1, aV1), gp_Pnt2d(aU2, aV2),
1406 aUSurf1f, aUSurf1l, thePeriod,
1407 theWL->Curve(), theTol3D, theTol2D, theFlForce);
1411 isTheFound1 = Standard_False;
1416 return Standard_True;
1419 //=======================================================================
1420 //function : SeekAdditionalPoints
1422 //=======================================================================
1423 static void SeekAdditionalPoints( const IntSurf_Quadric& theQuad1,
1424 const IntSurf_Quadric& theQuad2,
1425 const Handle(IntSurf_LineOn2S)& theLile,
1426 const stCoeffsValue& theCoeffs,
1427 const Standard_Integer theMinNbPoints,
1428 const Standard_Real theU2f,
1429 const Standard_Real theU2l,
1430 const Standard_Real theTol2D,
1431 const Standard_Real thePeriodOfSurf2,
1432 const Standard_Real theArccosFactor,
1433 const Standard_Boolean isTheReverse)
1435 Standard_Integer aNbPoints = theLile->NbPoints();
1436 if(aNbPoints >= theMinNbPoints)
1441 Standard_Real U1prec = 0.0, V1prec = 0.0, U2prec = 0.0, V2prec = 0.0;
1443 Standard_Integer aNbPointsPrev = 0;
1444 while(aNbPoints < theMinNbPoints && (aNbPoints != aNbPointsPrev))
1446 aNbPointsPrev = aNbPoints;
1447 for(Standard_Integer fp = 1, lp = 2; fp < aNbPoints; fp = lp + 1)
1449 Standard_Real U1f = 0.0, V1f = 0.0; //first point in 1st suraface
1450 Standard_Real U1l = 0.0, V1l = 0.0; //last point in 1st suraface
1452 Standard_Real U2f = 0.0, V2f = 0.0; //first point in 2nd suraface
1453 Standard_Real U2l = 0.0, V2l = 0.0; //last point in 2nd suraface
1459 theLile->Value(fp).ParametersOnS2(U1f, V1f);
1460 theLile->Value(lp).ParametersOnS2(U1l, V1l);
1462 theLile->Value(fp).ParametersOnS1(U2f, V2f);
1463 theLile->Value(lp).ParametersOnS1(U2l, V2l);
1467 theLile->Value(fp).ParametersOnS1(U1f, V1f);
1468 theLile->Value(lp).ParametersOnS1(U1l, V1l);
1470 theLile->Value(fp).ParametersOnS2(U2f, V2f);
1471 theLile->Value(lp).ParametersOnS2(U2l, V2l);
1474 if(Abs(U1l - U1f) <= theTol2D)
1476 //Step is minimal. It is not necessary to divide it.
1480 U1prec = 0.5*(U1f+U1l);
1482 Standard_Real anArg = theCoeffs.mB * cos(U1prec - theCoeffs.mFI1) + theCoeffs.mC;
1488 U2prec = theCoeffs.mFI2 + theArccosFactor*acos(anArg);
1489 InscribePoint(theU2f, theU2l, U2prec, theTol2D, thePeriodOfSurf2, Standard_False);
1493 V1prec = theCoeffs.mK21 * sin(U2prec) +
1494 theCoeffs.mK11 * sin(U1prec) +
1495 theCoeffs.mL21 * cos(U2prec) +
1496 theCoeffs.mL11 * cos(U1prec) + theCoeffs.mM1;
1497 V2prec = theCoeffs.mK22 * sin(U2prec) +
1498 theCoeffs.mK12 * sin(U1prec) +
1499 theCoeffs.mL22 * cos(U2prec) +
1500 theCoeffs.mL12 * cos(U1prec) + theCoeffs.mM2;
1502 aP1 = theQuad1.Value(U1prec, V1prec);
1503 aP2 = theQuad2.Value(U2prec, V2prec);
1505 gp_Pnt aPInt(0.5*(aP1.XYZ() + aP2.XYZ()));
1507 IntSurf_PntOn2S anIP;
1510 anIP.SetValue(aPInt, U2prec, V2prec, U1prec, V1prec);
1514 anIP.SetValue(aPInt, U1prec, V1prec, U2prec, V2prec);
1517 theLile->InsertBefore(lp, anIP);
1519 aNbPoints = theLile->NbPoints();
1520 if(aNbPoints >= theMinNbPoints)
1528 //=======================================================================
1529 //function : CriticalPointsComputing
1531 //=======================================================================
1532 static void CriticalPointsComputing(const stCoeffsValue& theCoeffs,
1533 const Standard_Real theUSurf1f,
1534 const Standard_Real theUSurf1l,
1535 const Standard_Real theUSurf2f,
1536 const Standard_Real theUSurf2l,
1537 const Standard_Real thePeriod,
1538 const Standard_Real theTol2D,
1539 const Standard_Integer theNbCritPointsMax,
1540 Standard_Real theU1crit[])
1543 theU1crit[1] = thePeriod;
1544 theU1crit[2] = theUSurf1f;
1545 theU1crit[3] = theUSurf1l;
1547 const Standard_Real aCOS = cos(theCoeffs.mFI2);
1548 const Standard_Real aBSB = Abs(theCoeffs.mB);
1549 if((theCoeffs.mC - aBSB <= aCOS) && (aCOS <= theCoeffs.mC + aBSB))
1551 Standard_Real anArg = (aCOS - theCoeffs.mC) / theCoeffs.mB;
1557 theU1crit[4] = -acos(anArg) + theCoeffs.mFI1;
1558 theU1crit[5] = acos(anArg) + theCoeffs.mFI1;
1561 Standard_Real aSf = cos(theUSurf2f - theCoeffs.mFI2);
1562 Standard_Real aSl = cos(theUSurf2l - theCoeffs.mFI2);
1565 theU1crit[6] = Abs((aSl - theCoeffs.mC) / theCoeffs.mB) < 1.0 ? -acos((aSl - theCoeffs.mC) / theCoeffs.mB) + theCoeffs.mFI1 : -Precision::Infinite();
1566 theU1crit[7] = Abs((aSf - theCoeffs.mC) / theCoeffs.mB) < 1.0 ? -acos((aSf - theCoeffs.mC) / theCoeffs.mB) + theCoeffs.mFI1 : Precision::Infinite();
1567 theU1crit[8] = Abs((aSf - theCoeffs.mC) / theCoeffs.mB) < 1.0 ? acos((aSf - theCoeffs.mC) / theCoeffs.mB) + theCoeffs.mFI1 : -Precision::Infinite();
1568 theU1crit[9] = Abs((aSl - theCoeffs.mC) / theCoeffs.mB) < 1.0 ? acos((aSl - theCoeffs.mC) / theCoeffs.mB) + theCoeffs.mFI1 : Precision::Infinite();
1570 //preparative treatment of array
1571 InscribeAndSortArray(theU1crit, theNbCritPointsMax, 0.0, thePeriod, theTol2D, thePeriod);
1572 for(Standard_Integer i = 1; i < theNbCritPointsMax; i++)
1574 Standard_Real &a = theU1crit[i],
1575 &b = theU1crit[i-1];
1576 const Standard_Real aRemain = fmod(Abs(a - b), thePeriod); // >= 0, because Abs(a - b) >= 0
1577 if((Abs(a - b) < theTol2D) || (aRemain < theTol2D) || (Abs(aRemain - thePeriod) < theTol2D))
1580 b = Precision::Infinite();
1585 //=======================================================================
1586 //function : IntCyCyTrim
1588 //=======================================================================
1589 Standard_Boolean IntCyCyTrim( const IntSurf_Quadric& theQuad1,
1590 const IntSurf_Quadric& theQuad2,
1591 const Standard_Real theTol3D,
1592 const Standard_Real theTol2D,
1593 const Bnd_Box2d& theUVSurf1,
1594 const Bnd_Box2d& theUVSurf2,
1595 const Standard_Boolean isTheReverse,
1596 Standard_Boolean& isTheEmpty,
1597 IntPatch_SequenceOfLine& theSlin,
1598 IntPatch_SequenceOfPoint& theSPnt)
1600 Standard_Real aUSurf1f = 0.0, //const
1604 Standard_Real aUSurf2f = 0.0, //const
1609 theUVSurf1.Get(aUSurf1f, aVSurf1f, aUSurf1l, aVSurf1l);
1610 theUVSurf2.Get(aUSurf2f, aVSurf2f, aUSurf2l, aVSurf2l);
1612 const Standard_Real aNulValue = 0.01*Precision::PConfusion();
1614 const gp_Cylinder& aCyl1 = theQuad1.Cylinder(),
1615 aCyl2 = theQuad2.Cylinder();
1617 IntAna_QuadQuadGeo anInter(aCyl1,aCyl2,theTol3D);
1619 if (!anInter.IsDone())
1621 return Standard_False;
1624 IntAna_ResultType aTypInt = anInter.TypeInter();
1626 if(aTypInt != IntAna_NoGeometricSolution)
1627 { //It is not necessary (because result is an analytic curve) or
1628 //it is impossible to make Walking-line.
1630 return Standard_False;
1635 const Standard_Integer aNbPoints = Min(Max(200, RealToInt(20.0*aCyl1.Radius())), 2000);
1636 const Standard_Real aPeriod = 2.0*M_PI;
1637 const Standard_Real aStepMin = theTol2D,
1638 aStepMax = (aUSurf1l-aUSurf1f)/IntToReal(aNbPoints);
1640 const stCoeffsValue anEquationCoeffs(aCyl1, aCyl2);
1643 const Standard_Integer aNbOfBoundaries = 2;
1644 Standard_Real aU1f[aNbOfBoundaries] = {-Precision::Infinite(), -Precision::Infinite()};
1645 Standard_Real aU1l[aNbOfBoundaries] = {Precision::Infinite(), Precision::Infinite()};
1647 if(anEquationCoeffs.mB > 0.0)
1649 if(anEquationCoeffs.mB + Abs(anEquationCoeffs.mC) < -1.0)
1650 {//There is NOT intersection
1651 return Standard_True;
1653 else if(anEquationCoeffs.mB + Abs(anEquationCoeffs.mC) <= 1.0)
1655 aU1f[0] = anEquationCoeffs.mFI1;
1656 aU1l[0] = aPeriod + anEquationCoeffs.mFI1;
1658 else if((1 + anEquationCoeffs.mC <= anEquationCoeffs.mB) &&
1659 (anEquationCoeffs.mB <= 1 - anEquationCoeffs.mC))
1661 Standard_Real anArg = -(anEquationCoeffs.mC + 1) / anEquationCoeffs.mB;
1667 const Standard_Real aDAngle = acos(anArg);
1668 //(U=[0;aDAngle]+aFI1) || (U=[2*PI-aDAngle;2*PI]+aFI1)
1669 aU1f[0] = anEquationCoeffs.mFI1;
1670 aU1l[0] = aDAngle + anEquationCoeffs.mFI1;
1671 aU1f[1] = aPeriod - aDAngle + anEquationCoeffs.mFI1;
1672 aU1l[1] = aPeriod + anEquationCoeffs.mFI1;
1674 else if((1 - anEquationCoeffs.mC <= anEquationCoeffs.mB) &&
1675 (anEquationCoeffs.mB <= 1 + anEquationCoeffs.mC))
1677 Standard_Real anArg = (1 - anEquationCoeffs.mC) / anEquationCoeffs.mB;
1683 const Standard_Real aDAngle = acos(anArg);
1684 //U=[aDAngle;2*PI-aDAngle]+aFI1
1686 aU1f[0] = aDAngle + anEquationCoeffs.mFI1;
1687 aU1l[0] = aPeriod - aDAngle + anEquationCoeffs.mFI1;
1689 else if(anEquationCoeffs.mB - Abs(anEquationCoeffs.mC) >= 1.0)
1691 Standard_Real anArg1 = (1 - anEquationCoeffs.mC) / anEquationCoeffs.mB,
1692 anArg2 = -(anEquationCoeffs.mC + 1) / anEquationCoeffs.mB;
1703 const Standard_Real aDAngle1 = acos(anArg1), aDAngle2 = acos(anArg2);
1704 //(U=[aDAngle1;aDAngle2]+aFI1) ||
1705 //(U=[2*PI-aDAngle2;2*PI-aDAngle1]+aFI1)
1707 aU1f[0] = aDAngle1 + anEquationCoeffs.mFI1;
1708 aU1l[0] = aDAngle2 + anEquationCoeffs.mFI1;
1709 aU1f[1] = aPeriod - aDAngle2 + anEquationCoeffs.mFI1;
1710 aU1l[1] = aPeriod - aDAngle1 + anEquationCoeffs.mFI1;
1714 Standard_Failure::Raise("Error. Exception. Unhandled case (Range computation)!");
1717 else if(anEquationCoeffs.mB < 0.0)
1719 if(anEquationCoeffs.mB + Abs(anEquationCoeffs.mC) > 1.0)
1720 {//There is NOT intersection
1721 return Standard_True;
1723 else if(-anEquationCoeffs.mB + Abs(anEquationCoeffs.mC) <= 1.0)
1725 aU1f[0] = anEquationCoeffs.mFI1;
1726 aU1l[0] = aPeriod + anEquationCoeffs.mFI1;
1728 else if((-anEquationCoeffs.mC - 1 <= anEquationCoeffs.mB) &&
1729 ( anEquationCoeffs.mB <= anEquationCoeffs.mC - 1))
1731 Standard_Real anArg = (1 - anEquationCoeffs.mC) / anEquationCoeffs.mB;
1737 const Standard_Real aDAngle = acos(anArg);
1738 //(U=[0;aDAngle]+aFI1) || (U=[2*PI-aDAngle;2*PI]+aFI1)
1740 aU1f[0] = anEquationCoeffs.mFI1;
1741 aU1l[0] = aDAngle + anEquationCoeffs.mFI1;
1742 aU1f[1] = aPeriod - aDAngle + anEquationCoeffs.mFI1;
1743 aU1l[1] = aPeriod + anEquationCoeffs.mFI1;
1745 else if((anEquationCoeffs.mC - 1 <= anEquationCoeffs.mB) &&
1746 (anEquationCoeffs.mB <= -anEquationCoeffs.mB - 1))
1748 Standard_Real anArg = -(anEquationCoeffs.mC + 1) / anEquationCoeffs.mB;
1754 const Standard_Real aDAngle = acos(anArg);
1755 //U=[aDAngle;2*PI-aDAngle]+aFI1
1757 aU1f[0] = aDAngle + anEquationCoeffs.mFI1;
1758 aU1l[0] = aPeriod - aDAngle + anEquationCoeffs.mFI1;
1760 else if(-anEquationCoeffs.mB - Abs(anEquationCoeffs.mC) >= 1.0)
1762 Standard_Real anArg1 = -(anEquationCoeffs.mC + 1) / anEquationCoeffs.mB,
1763 anArg2 = (1 - anEquationCoeffs.mC) / anEquationCoeffs.mB;
1774 const Standard_Real aDAngle1 = acos(anArg1), aDAngle2 = acos(anArg2);
1775 //(U=[aDAngle1;aDAngle2]+aFI1) ||
1776 //(U=[2*PI-aDAngle2;2*PI-aDAngle1]+aFI1)
1778 aU1f[0] = aDAngle1 + anEquationCoeffs.mFI1;
1779 aU1l[0] = aDAngle2 + anEquationCoeffs.mFI1;
1780 aU1f[1] = aPeriod - aDAngle2 + anEquationCoeffs.mFI1;
1781 aU1l[1] = aPeriod - aDAngle1 + anEquationCoeffs.mFI1;
1785 Standard_Failure::Raise("Error. Exception. Unhandled case (Range computation)!");
1790 Standard_Failure::Raise("Error. Exception. Unhandled case (B-parameter computation)!");
1793 for(Standard_Integer i = 0; i < aNbOfBoundaries; i++)
1795 if(Precision::IsInfinite(aU1f[i]) && Precision::IsInfinite(aU1l[i]))
1798 InscribeInterval(aUSurf1f, aUSurf1l, aU1f[i], aU1l[i], theTol2D, aPeriod);
1801 if( !Precision::IsInfinite(aU1f[0]) && !Precision::IsInfinite(aU1f[1]) &&
1802 !Precision::IsInfinite(aU1l[0]) && !Precision::IsInfinite(aU1l[1]))
1804 if( ((aU1f[1] <= aU1l[0]) || (aU1l[1] <= aU1l[0])) &&
1805 ((aU1f[0] <= aU1l[1]) || (aU1l[0] <= aU1l[1])))
1806 {//Join all intervals to one
1807 aU1f[0] = Min(aU1f[0], aU1f[1]);
1808 aU1l[0] = Max(aU1l[0], aU1l[1]);
1810 aU1f[1] = -Precision::Infinite();
1811 aU1l[1] = Precision::Infinite();
1816 //[0...1] - in these points parameter U1 goes through
1817 // the seam-edge of the first cylinder.
1818 //[2...3] - First and last U1 parameter.
1819 //[4...5] - in these points parameter U2 goes through
1820 // the seam-edge of the second cylinder.
1821 //[6...9] - in these points an intersection line goes through
1822 // U-boundaries of the second surface.
1823 const Standard_Integer aNbCritPointsMax = 10;
1824 Standard_Real anU1crit[aNbCritPointsMax] = {Precision::Infinite(),
1825 Precision::Infinite(),
1826 Precision::Infinite(),
1827 Precision::Infinite(),
1828 Precision::Infinite(),
1829 Precision::Infinite(),
1830 Precision::Infinite(),
1831 Precision::Infinite(),
1832 Precision::Infinite(),
1833 Precision::Infinite()};
1835 CriticalPointsComputing(anEquationCoeffs, aUSurf1f, aUSurf1l, aUSurf2f, aUSurf2l,
1836 aPeriod, theTol2D, aNbCritPointsMax, anU1crit);
1839 //Getting Walking-line
1841 for(Standard_Integer aCurInterval = 0; aCurInterval < aNbOfBoundaries; aCurInterval++)
1843 if(Precision::IsInfinite(aU1f[aCurInterval]) && Precision::IsInfinite(aU1l[aCurInterval]))
1846 Standard_Boolean isAddedIntoWL1 = Standard_False, isAddedIntoWL2 = Standard_False;
1848 Standard_Real anUf = aU1f[aCurInterval], anUl = aU1l[aCurInterval];
1849 const Standard_Boolean isDeltaPeriod = IsEqual(anUl-anUf, aPeriod);
1851 //Inscribe and sort critical points
1852 InscribeAndSortArray(anU1crit, aNbCritPointsMax, anUf, anUl, theTol2D, aPeriod);
1856 Handle(IntSurf_LineOn2S) aL2S1 = new IntSurf_LineOn2S();
1857 Handle(IntSurf_LineOn2S) aL2S2 = new IntSurf_LineOn2S();
1859 Handle(IntPatch_WLine) aWLine1 = new IntPatch_WLine(aL2S1, Standard_False);
1860 Handle(IntPatch_WLine) aWLine2 = new IntPatch_WLine(aL2S2, Standard_False);
1862 Standard_Integer aWL1FindStatus = 0, aWL2FindStatus = 0;
1863 Standard_Boolean isAddingWL1Enabled = Standard_True,
1864 isAddingWL2Enabled = Standard_True;
1866 Standard_Real anU1 = anUf;
1868 Standard_Real aCriticalDelta[aNbCritPointsMax];
1869 for(Standard_Integer i = 0; i < aNbCritPointsMax; i++)
1870 aCriticalDelta[i] = anU1 - anU1crit[i];
1872 Standard_Real aV11Prev = 0.0,
1876 Standard_Boolean isFirst = Standard_True;
1882 if(IsEqual(anU1, anUl))
1884 //if isAddedIntoWL* == TRUE WLine contains only one point
1885 //(which was end point of previous WLine). If we will
1886 //add point found on the current step WLine will contain only
1887 //two points. At that both these points will be equal to the
1888 //points found earlier. Therefore, new WLine will repeat
1889 //already existing WLine. Consequently, it is necessary
1890 //to forbid building new line in this case.
1892 isAddingWL1Enabled = !isAddedIntoWL1;
1893 isAddingWL2Enabled = !isAddedIntoWL2;
1897 for(Standard_Integer i = 0; i < aNbCritPointsMax; i++)
1899 if((anU1 - anU1crit[i])*aCriticalDelta[i] < 0.0)
1908 Standard_Real anArg = anEquationCoeffs.mB *
1909 cos(anU1 - anEquationCoeffs.mFI1) + anEquationCoeffs.mC;
1911 if(aNulValue > 1.0 - anArg)
1913 if(anArg + 1.0 < aNulValue)
1916 Standard_Real aU21 = anEquationCoeffs.mFI2 + acos(anArg);
1917 InscribePoint(aUSurf2f, aUSurf2l, aU21, theTol2D, aPeriod, Standard_False);
1920 const Standard_Integer aNbPntsWL1 = aWLine1.IsNull() ? 0 :
1921 aWLine1->Curve()->NbPoints();
1923 {//the line have not contained any points yet
1924 if(((aUSurf2l - aUSurf2f) >= aPeriod) &&
1925 ((Abs(aU21-aUSurf2f) < theTol2D) || (Abs(aU21-aUSurf2l) < theTol2D)))
1927 const Standard_Real anU1Temp = anU1 + aStepMin;
1928 Standard_Real anArgTemp = anEquationCoeffs.mB *
1929 cos(anU1Temp - anEquationCoeffs.mFI1) + anEquationCoeffs.mC;
1931 if(aNulValue > 1.0 - anArg)
1933 if(anArg + 1.0 < aNulValue)
1936 Standard_Real aU2Temp = anEquationCoeffs.mFI2 + acos(anArgTemp);
1937 InscribePoint(aUSurf2f, aUSurf2l, aU2Temp, theTol2D, aPeriod, Standard_False);
1938 if(2.0*Abs(aU2Temp - aU21) > aPeriod)
1950 if(((aUSurf2l - aUSurf2f) >= aPeriod) &&
1951 ((Abs(aU21-aUSurf2f) < theTol2D) || (Abs(aU21-aUSurf2l) < theTol2D)))
1953 Standard_Real aU2prev = 0.0, aV2prev = 0.0;
1955 aWLine1->Curve()->Value(aNbPntsWL1).ParametersOnS1(aU2prev, aV2prev);
1957 aWLine1->Curve()->Value(aNbPntsWL1).ParametersOnS2(aU2prev, aV2prev);
1959 if(2.0*Abs(aU2prev - aU21) > aPeriod)
1969 Standard_Real aU22 = anEquationCoeffs.mFI2 - acos(anArg);
1970 InscribePoint(aUSurf2f, aUSurf2l, aU22, theTol2D, aPeriod, Standard_False);
1972 const Standard_Integer aNbPntsWL2 = aWLine2.IsNull() ? 0 :
1973 aWLine2->Curve()->NbPoints();
1975 {//the line have not contained any points yet
1976 if(((aUSurf2l - aUSurf2f) >= aPeriod) &&
1977 ((Abs(aU22-aUSurf2f) < theTol2D) || (Abs(aU22-aUSurf2l) < theTol2D)))
1979 const Standard_Real anU1Temp = anU1 + aStepMin;
1980 Standard_Real anArgTemp = anEquationCoeffs.mB *
1981 cos(anU1Temp - anEquationCoeffs.mFI1) + anEquationCoeffs.mC;
1983 if(aNulValue > 1.0 - anArg)
1985 if(anArg + 1.0 < aNulValue)
1988 Standard_Real aU2Temp = anEquationCoeffs.mFI2 - acos(anArgTemp);
1989 InscribePoint(aUSurf2f, aUSurf2l, aU2Temp, theTol2D, aPeriod, Standard_False);
1990 if(2.0*Abs(aU2Temp - aU22) > aPeriod)
2002 if(((aUSurf2l - aUSurf2f) >= aPeriod) &&
2003 ((Abs(aU22-aUSurf2f) < theTol2D) || (Abs(aU22-aUSurf2l) < theTol2D)))
2005 Standard_Real aU2prev = 0.0, aV2prev = 0.0;
2007 aWLine2->Curve()->Value(aNbPntsWL2).ParametersOnS1(aU2prev, aV2prev);
2009 aWLine2->Curve()->Value(aNbPntsWL2).ParametersOnS2(aU2prev, aV2prev);
2011 if(2.0*Abs(aU2prev - aU22) > aPeriod)
2021 const Standard_Real aV11 = anEquationCoeffs.mK21 * sin(aU21) +
2022 anEquationCoeffs.mK11 * sin(anU1) +
2023 anEquationCoeffs.mL21 * cos(aU21) +
2024 anEquationCoeffs.mL11 * cos(anU1) + anEquationCoeffs.mM1;
2025 const Standard_Real aV12 = anEquationCoeffs.mK21 * sin(aU22) +
2026 anEquationCoeffs.mK11 * sin(anU1) +
2027 anEquationCoeffs.mL21 * cos(aU22) +
2028 anEquationCoeffs.mL11 * cos(anU1) + anEquationCoeffs.mM1;
2029 const Standard_Real aV21 = anEquationCoeffs.mK22 * sin(aU21) +
2030 anEquationCoeffs.mK12 * sin(anU1) +
2031 anEquationCoeffs.mL22 * cos(aU21) +
2032 anEquationCoeffs.mL12 * cos(anU1) + anEquationCoeffs.mM2;
2033 const Standard_Real aV22 = anEquationCoeffs.mK22 * sin(aU22) +
2034 anEquationCoeffs.mK12 * sin(anU1) +
2035 anEquationCoeffs.mL22 * cos(aU22) +
2036 anEquationCoeffs.mL12 * cos(anU1) + anEquationCoeffs.mM2;
2044 isFirst = Standard_False;
2047 if(isAddingWL1Enabled)
2049 if( ((aUSurf2f-aU21) <= theTol2D) &&
2050 ((aU21-aUSurf2l) <= theTol2D) &&
2051 ((aVSurf1f - aV11) <= theTol2D) &&
2052 ((aV11 - aVSurf1l) <= theTol2D) &&
2053 ((aVSurf2f - aV21) <= theTol2D) && ((aV21 - aVSurf2l) <= theTol2D))
2055 Standard_Boolean isForce = Standard_False;
2058 Standard_Boolean isFound1 = Standard_False, isFound2 = Standard_False;
2060 if(((aUSurf2l - aUSurf2f) >= aPeriod) && (Abs(anU1-aUSurf1l) < theTol2D))
2062 isForce = Standard_True;
2065 AddBoundaryPoint(theQuad1, theQuad2, aWLine1, anEquationCoeffs,
2066 theUVSurf1, theUVSurf2, theTol3D, theTol2D, aPeriod,
2067 aNulValue, anU1, aU21, aV11, aV11Prev,
2068 aV21, aV21Prev, isTheReverse,
2069 1.0, isForce, isFound1, isFound2);
2071 if(isFound1 || isFound2)
2077 if((aWL1FindStatus != 2) || (aWLine1->NbPnts() >= 1))
2079 if(AddPointIntoWL(theQuad1, theQuad2, isTheReverse,
2080 gp_Pnt2d(anU1, aV11), gp_Pnt2d(aU21, aV21),
2081 aUSurf1f, aUSurf1l, aPeriod,
2082 aWLine1->Curve(), theTol3D, theTol2D, isForce))
2093 if(aWL1FindStatus == 1)
2095 Standard_Boolean isFound1 = Standard_False, isFound2 = Standard_False;
2097 AddBoundaryPoint(theQuad1, theQuad2, aWLine1, anEquationCoeffs,
2098 theUVSurf1, theUVSurf2, theTol3D, theTol2D, aPeriod,
2099 aNulValue, anU1, aU21, aV11, aV11Prev,
2100 aV21, aV21Prev, isTheReverse,
2101 1.0, Standard_False, isFound1, isFound2);
2103 if(isFound1 || isFound2)
2104 aWL1FindStatus = 2; //start a new line
2109 if(isAddingWL2Enabled)
2111 if( ((aUSurf2f-aU22) <= theTol2D) &&
2112 ((aU22-aUSurf2l) <= theTol2D) &&
2113 ((aVSurf1f - aV12) <= theTol2D) &&
2114 ((aV12 - aVSurf1l) <= theTol2D) &&
2115 ((aVSurf2f - aV22) <= theTol2D) &&
2116 ((aV22 - aVSurf2l) <= theTol2D))
2118 Standard_Boolean isForce = Standard_False;
2122 Standard_Boolean isFound1 = Standard_False, isFound2 = Standard_False;
2124 if(((aUSurf2l - aUSurf2f) >= aPeriod) && (Abs(anU1-aUSurf1l) < theTol2D))
2126 isForce = Standard_True;
2129 AddBoundaryPoint(theQuad1, theQuad2, aWLine2, anEquationCoeffs,
2130 theUVSurf1, theUVSurf2, theTol3D, theTol2D, aPeriod,
2131 aNulValue, anU1, aU22, aV12, aV12Prev,
2132 aV22, aV22Prev, isTheReverse,
2133 -1.0, isForce, isFound1, isFound2);
2135 if(isFound1 || isFound2)
2141 if((aWL2FindStatus != 2) || (aWLine2->NbPnts() >= 1))
2143 if(AddPointIntoWL(theQuad1, theQuad2, isTheReverse,
2144 gp_Pnt2d(anU1, aV12), gp_Pnt2d(aU22, aV22),
2145 aUSurf1f, aUSurf1l, aPeriod,
2146 aWLine2->Curve(), theTol3D, theTol2D, isForce))
2157 if(aWL2FindStatus == 1)
2159 Standard_Boolean isFound1 = Standard_False, isFound2 = Standard_False;
2161 AddBoundaryPoint(theQuad1, theQuad2, aWLine2, anEquationCoeffs,
2162 theUVSurf1, theUVSurf2, theTol3D, theTol2D, aPeriod,
2163 aNulValue, anU1, aU22, aV12, aV12Prev,
2164 aV22, aV22Prev, isTheReverse,
2165 -1.0, Standard_False, isFound1, isFound2);
2167 if(isFound1 || isFound2)
2168 aWL2FindStatus = 2; //start a new line
2178 if((aWL1FindStatus == 2) || (aWL2FindStatus == 2))
2179 {//current lines are filled. Go to the next lines
2184 Standard_Real aFact1 = !IsEqual(sin(aU21 - anEquationCoeffs.mFI2), 0.0) ?
2185 anEquationCoeffs.mK1 * sin(anU1 - anEquationCoeffs.mFIV1) +
2186 anEquationCoeffs.mL1 * anEquationCoeffs.mB * sin(aU21 - anEquationCoeffs.mPSIV1) *
2187 sin(anU1 - anEquationCoeffs.mFI1)/sin(aU21-anEquationCoeffs.mFI2) : 0.0,
2188 aFact2 = !IsEqual(sin(aU22-anEquationCoeffs.mFI2), 0.0) ?
2189 anEquationCoeffs.mK1 * sin(anU1 - anEquationCoeffs.mFIV1) +
2190 anEquationCoeffs.mL1 * anEquationCoeffs.mB * sin(aU22 - anEquationCoeffs.mPSIV1) *
2191 sin(anU1 - anEquationCoeffs.mFI1)/sin(aU22-anEquationCoeffs.mFI2) : 0.0;
2193 Standard_Real aDeltaV1 = (aVSurf1l - aVSurf1f)/IntToReal(aNbPoints);
2195 if((aV11 < aVSurf1f) && (aFact1 < 0.0))
2196 {//Make close to aVSurf1f by increasing anU1 (for the 1st line)
2197 aDeltaV1 = Min(aDeltaV1, Abs(aV11-aVSurf1f));
2200 if((aV12 < aVSurf1f) && (aFact2 < 0.0))
2201 {//Make close to aVSurf1f by increasing anU1 (for the 2nd line)
2202 aDeltaV1 = Min(aDeltaV1, Abs(aV12-aVSurf1f));
2205 if((aV11 > aVSurf1l) && (aFact1 > 0.0))
2206 {//Make close to aVSurf1l by increasing anU1 (for the 1st line)
2207 aDeltaV1 = Min(aDeltaV1, Abs(aV11-aVSurf1l));
2210 if((aV12 > aVSurf1l) && (aFact2 > 0.0))
2211 {//Make close to aVSurf1l by increasing anU1 (for the 1st line)
2212 aDeltaV1 = Min(aDeltaV1, Abs(aV12-aVSurf1l));
2215 Standard_Real aDeltaU1L1 = !IsEqual(aFact1,0.0)? Abs(aDeltaV1/aFact1) : aStepMax,
2216 aDeltaU1L2 = !IsEqual(aFact2,0.0)? Abs(aDeltaV1/aFact2) : aStepMax;
2218 const Standard_Real aDeltaU1V1 = Min(aDeltaU1L1, aDeltaU1L2);
2220 ///////////////////////////
2221 aFact1 = !IsEqual(sin(aU21-anEquationCoeffs.mFI2), 0.0) ?
2222 anEquationCoeffs.mK2 * sin(anU1 - anEquationCoeffs.mFIV2) +
2223 anEquationCoeffs.mL2 * anEquationCoeffs.mB * sin(aU21 - anEquationCoeffs.mPSIV2) *
2224 sin(anU1 - anEquationCoeffs.mFI1)/sin(aU21 - anEquationCoeffs.mFI2) : 0.0;
2225 aFact2 = !IsEqual(sin(aU22-anEquationCoeffs.mFI2), 0.0) ?
2226 anEquationCoeffs.mK2 * sin(anU1 - anEquationCoeffs.mFIV2) +
2227 anEquationCoeffs.mL2 * anEquationCoeffs.mB * sin(aU22 - anEquationCoeffs.mPSIV2) *
2228 sin(anU1 - anEquationCoeffs.mFI1)/sin(aU22 - anEquationCoeffs.mFI2) : 0.0;
2230 Standard_Real aDeltaV2 = (aVSurf2l - aVSurf2f)/IntToReal(aNbPoints);
2232 if((aV21 < aVSurf2f) && (aFact1 < 0.0))
2233 {//Make close to aVSurf2f by increasing anU1 (for the 1st line)
2234 aDeltaV2 = Min(aDeltaV2, Abs(aV21-aVSurf2f));
2237 if((aV22 < aVSurf2f) && (aFact2 < 0.0))
2238 {//Make close to aVSurf1f by increasing anU1 (for the 2nd line)
2239 aDeltaV2 = Min(aDeltaV2, Abs(aV22-aVSurf2f));
2242 if((aV21 > aVSurf2l) && (aFact1 > 0.0))
2243 {//Make close to aVSurf1l by increasing anU1 (for the 1st line)
2244 aDeltaV2 = Min(aDeltaV2, Abs(aV21-aVSurf2l));
2247 if((aV22 > aVSurf2l) && (aFact2 > 0.0))
2248 {//Make close to aVSurf1l by increasing anU1 (for the 1st line)
2249 aDeltaV2 = Min(aDeltaV2, Abs(aV22-aVSurf1l));
2252 aDeltaU1L1 = !IsEqual(aFact1,0.0)? Abs(aDeltaV2/aFact1) : aStepMax;
2253 aDeltaU1L2 = !IsEqual(aFact2,0.0)? Abs(aDeltaV2/aFact2) : aStepMax;
2255 const Standard_Real aDeltaU1V2 = Min(aDeltaU1L1, aDeltaU1L2);
2257 Standard_Real aDeltaU1 = Min(aDeltaU1V1, aDeltaU1V2);
2259 if(aDeltaU1 < aStepMin)
2260 aDeltaU1 = aStepMin;
2262 if(aDeltaU1 > aStepMax)
2263 aDeltaU1 = aStepMax;
2267 const Standard_Real aDiff = anU1 - anUl;
2268 if((0.0 < aDiff) && (aDiff < aDeltaU1-Precision::PConfusion()))
2273 if(aWLine1->NbPnts() != 1)
2274 isAddedIntoWL1 = Standard_False;
2276 if(aWLine2->NbPnts() != 1)
2277 isAddedIntoWL2 = Standard_False;
2280 if((aWLine1->NbPnts() == 1) && (!isAddedIntoWL1))
2282 isTheEmpty = Standard_False;
2283 Standard_Real u1, v1, u2, v2;
2284 aWLine1->Point(1).Parameters(u1, v1, u2, v2);
2286 aP.SetParameter(u1);
2287 aP.SetParameters(u1, v1, u2, v2);
2288 aP.SetTolerance(theTol3D);
2289 aP.SetValue(aWLine1->Point(1).Value());
2293 else if(aWLine1->NbPnts() > 1)
2295 Standard_Boolean isGood = Standard_True;
2297 if(aWLine1->NbPnts() == 2)
2299 const IntSurf_PntOn2S& aPf = aWLine1->Point(1);
2300 const IntSurf_PntOn2S& aPl = aWLine1->Point(2);
2302 if(aPf.IsSame(aPl, Precision::Confusion()))
2303 isGood = Standard_False;
2308 isTheEmpty = Standard_False;
2309 isAddedIntoWL1 = Standard_True;
2310 SeekAdditionalPoints( theQuad1, theQuad2, aWLine1->Curve(),
2311 anEquationCoeffs, aNbPoints, aUSurf2f, aUSurf2l,
2312 theTol2D, aPeriod, 1.0, isTheReverse);
2314 aWLine1->ComputeVertexParameters(theTol3D);
2315 theSlin.Append(aWLine1);
2320 isAddedIntoWL1 = Standard_False;
2323 if((aWLine2->NbPnts() == 1) && (!isAddedIntoWL2))
2325 isTheEmpty = Standard_False;
2326 Standard_Real u1, v1, u2, v2;
2327 aWLine2->Point(1).Parameters(u1, v1, u2, v2);
2329 aP.SetParameter(u1);
2330 aP.SetParameters(u1, v1, u2, v2);
2331 aP.SetTolerance(theTol3D);
2332 aP.SetValue(aWLine2->Point(1).Value());
2336 else if(aWLine2->NbPnts() > 1)
2338 Standard_Boolean isGood = Standard_True;
2339 if(aWLine2->NbPnts() == 2)
2341 const IntSurf_PntOn2S& aPf = aWLine2->Point(1);
2342 const IntSurf_PntOn2S& aPl = aWLine2->Point(2);
2344 if(aPf.IsSame(aPl, Precision::Confusion()))
2345 isGood = Standard_False;
2350 isTheEmpty = Standard_False;
2351 isAddedIntoWL2 = Standard_True;
2353 SeekAdditionalPoints(theQuad1, theQuad2, aWLine2->Curve(),
2354 anEquationCoeffs, aNbPoints, aUSurf2f, aUSurf2l,
2355 theTol2D, aPeriod, -1.0, isTheReverse);
2357 aWLine2->ComputeVertexParameters(theTol3D);
2358 theSlin.Append(aWLine2);
2363 isAddedIntoWL2 = Standard_False;
2368 if(theSlin.Length() > 0)
2370 for(Standard_Integer aNumOfLine = 2; aNumOfLine <= theSlin.Length(); aNumOfLine++)
2372 const Handle(IntPatch_WLine)& aWLine = Handle(IntPatch_WLine)::DownCast(theSlin.Value(aNumOfLine));
2374 const IntSurf_PntOn2S& aPntFWL = aWLine->Point(1);
2376 Standard_Real aU1 = 0.0, aU2 = 0.0, aV1 = 0.0, aV2 = 0.0;
2377 aPntFWL.Parameters(aU1, aV1, aU2, aV2);
2379 if( IsEqual(aU1, 0.0) || IsEqual(aU1, aPeriod))
2381 theSlin.Exchange(1, aNumOfLine);
2386 for(Standard_Integer aNumOfLine1 = 1; aNumOfLine1 <= theSlin.Length(); aNumOfLine1++)
2388 const Handle(IntPatch_WLine)& aWLine1 = Handle(IntPatch_WLine)::DownCast(theSlin.Value(aNumOfLine1));
2390 const Standard_Integer aNbPntsWL1 = aWLine1->NbPnts();
2391 const IntSurf_PntOn2S& aPntFWL1 = aWLine1->Point(1);
2392 const IntSurf_PntOn2S& aPntLWL1 = aWLine1->Point(aNbPntsWL1);
2394 for(Standard_Integer aNPt = 1; aNPt <= theSPnt.Length(); aNPt++)
2396 const IntSurf_PntOn2S aPntCur = theSPnt.Value(aNPt).PntOn2S();
2398 if( aPntCur.IsSame(aPntFWL1, Precision::Confusion()) ||
2399 aPntCur.IsSame(aPntLWL1, Precision::Confusion()))
2401 theSPnt.Remove(aNPt);
2406 Standard_Boolean hasBeenRemoved = Standard_False;
2407 for(Standard_Integer aNumOfLine2 = aNumOfLine1 + 1; aNumOfLine2 <= theSlin.Length(); aNumOfLine2++)
2409 const Handle(IntPatch_WLine)& aWLine2 = Handle(IntPatch_WLine)::DownCast(theSlin.Value(aNumOfLine2));
2411 const Standard_Integer aNbPntsWL1 = aWLine1->NbPnts();
2412 const Standard_Integer aNbPntsWL2 = aWLine2->NbPnts();
2414 const IntSurf_PntOn2S& aPntFWL1 = aWLine1->Point(1);
2415 const IntSurf_PntOn2S& aPntLWL1 = aWLine1->Point(aNbPntsWL1);
2417 const IntSurf_PntOn2S& aPntFWL2 = aWLine2->Point(1);
2418 const IntSurf_PntOn2S& aPntLWL2 = aWLine2->Point(aNbPntsWL2);
2420 if(aPntFWL1.IsSame(aPntFWL2, Precision::Confusion()))
2422 Standard_Real aU11 = 0.0, aU12 = 0.0, aV11 = 0.0, aV12 = 0.0;
2423 Standard_Real aU21 = 0.0, aU22 = 0.0, aV21 = 0.0, aV22 = 0.0;
2425 aPntFWL1.Parameters(aU11, aV11, aU12, aV12);
2426 aPntFWL2.Parameters(aU21, aV21, aU22, aV22);
2428 if( !(IsEqual(fmod(aU11, aPeriod), 0.0) ||
2429 IsEqual(fmod(aU12, aPeriod), 0.0) ||
2430 IsEqual(fmod(aU21, aPeriod), 0.0) ||
2431 IsEqual(fmod(aU22, aPeriod), 0.0) ||
2432 IsEqual(aU11, aUSurf1f) || IsEqual(aU11, aUSurf1l) ||
2433 IsEqual(aU21, aUSurf1f) || IsEqual(aU21, aUSurf1l) ||
2434 IsEqual(aU12, aUSurf2f) || IsEqual(aU12, aUSurf2l) ||
2435 IsEqual(aU22, aUSurf2f) || IsEqual(aU22, aUSurf2l)))
2437 aWLine1->ClearVertexes();
2438 for(Standard_Integer aNPt = 1; aNPt <= aNbPntsWL2; aNPt++)
2440 const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt);
2441 aWLine1->Curve()->InsertBefore(1, aPt);
2444 aWLine1->ComputeVertexParameters(theTol3D);
2446 theSlin.Remove(aNumOfLine2);
2448 hasBeenRemoved = Standard_True;
2454 if(aPntFWL1.IsSame(aPntLWL2, Precision::Confusion()))
2456 Standard_Real aU11 = 0.0, aU12 = 0.0, aV11 = 0.0, aV12 = 0.0;
2457 Standard_Real aU21 = 0.0, aU22 = 0.0, aV21 = 0.0, aV22 = 0.0;
2459 aPntFWL1.Parameters(aU11, aV11, aU12, aV12);
2460 aPntLWL2.Parameters(aU21, aV21, aU22, aV22);
2462 if( !(IsEqual(fmod(aU11, aPeriod), 0.0) ||
2463 IsEqual(fmod(aU12, aPeriod), 0.0) ||
2464 IsEqual(fmod(aU21, aPeriod), 0.0) ||
2465 IsEqual(fmod(aU22, aPeriod), 0.0) ||
2466 IsEqual(aU11, aUSurf1f) || IsEqual(aU11, aUSurf1l) ||
2467 IsEqual(aU21, aUSurf1f) || IsEqual(aU21, aUSurf1l) ||
2468 IsEqual(aU12, aUSurf2f) || IsEqual(aU12, aUSurf2l) ||
2469 IsEqual(aU22, aUSurf2f) || IsEqual(aU22, aUSurf2l)))
2471 aWLine1->ClearVertexes();
2472 for(Standard_Integer aNPt = aNbPntsWL2; aNPt >= 1; aNPt--)
2474 const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt);
2475 aWLine1->Curve()->InsertBefore(1, aPt);
2478 aWLine1->ComputeVertexParameters(theTol3D);
2480 theSlin.Remove(aNumOfLine2);
2482 hasBeenRemoved = Standard_True;
2488 if(aPntLWL1.IsSame(aPntFWL2, Precision::Confusion()))
2490 Standard_Real aU11 = 0.0, aU12 = 0.0, aV11 = 0.0, aV12 = 0.0;
2491 Standard_Real aU21 = 0.0, aU22 = 0.0, aV21 = 0.0, aV22 = 0.0;
2493 aPntLWL1.Parameters(aU11, aV11, aU12, aV12);
2494 aPntFWL2.Parameters(aU21, aV21, aU22, aV22);
2496 if( !(IsEqual(fmod(aU11, aPeriod), 0.0) ||
2497 IsEqual(fmod(aU12, aPeriod), 0.0) ||
2498 IsEqual(fmod(aU21, aPeriod), 0.0) ||
2499 IsEqual(fmod(aU22, aPeriod), 0.0) ||
2500 IsEqual(aU11, aUSurf1f) || IsEqual(aU11, aUSurf1l) ||
2501 IsEqual(aU21, aUSurf1f) || IsEqual(aU21, aUSurf1l) ||
2502 IsEqual(aU12, aUSurf2f) || IsEqual(aU12, aUSurf2l) ||
2503 IsEqual(aU22, aUSurf2f) || IsEqual(aU22, aUSurf2l)))
2505 aWLine1->ClearVertexes();
2506 for(Standard_Integer aNPt = 1; aNPt <= aNbPntsWL2; aNPt++)
2508 const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt);
2509 aWLine1->Curve()->Add(aPt);
2512 aWLine1->ComputeVertexParameters(theTol3D);
2514 theSlin.Remove(aNumOfLine2);
2516 hasBeenRemoved = Standard_True;
2522 if(aPntLWL1.IsSame(aPntLWL2, Precision::Confusion()))
2524 Standard_Real aU11 = 0.0, aU12 = 0.0, aV11 = 0.0, aV12 = 0.0;
2525 Standard_Real aU21 = 0.0, aU22 = 0.0, aV21 = 0.0, aV22 = 0.0;
2527 aPntLWL1.Parameters(aU11, aV11, aU12, aV12);
2528 aPntLWL2.Parameters(aU21, aV21, aU22, aV22);
2530 if( !(IsEqual(fmod(aU11, aPeriod), 0.0) ||
2531 IsEqual(fmod(aU12, aPeriod), 0.0) ||
2532 IsEqual(fmod(aU21, aPeriod), 0.0) ||
2533 IsEqual(fmod(aU22, aPeriod), 0.0) ||
2534 IsEqual(aU11, aUSurf1f) || IsEqual(aU11, aUSurf1l) ||
2535 IsEqual(aU21, aUSurf1f) || IsEqual(aU21, aUSurf1l) ||
2536 IsEqual(aU12, aUSurf2f) || IsEqual(aU12, aUSurf2l) ||
2537 IsEqual(aU22, aUSurf2f) || IsEqual(aU22, aUSurf2l)))
2539 aWLine1->ClearVertexes();
2540 for(Standard_Integer aNPt = aNbPntsWL2; aNPt >= 1; aNPt--)
2542 const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt);
2543 aWLine1->Curve()->Add(aPt);
2546 aWLine1->ComputeVertexParameters(theTol3D);
2548 theSlin.Remove(aNumOfLine2);
2550 hasBeenRemoved = Standard_True;
2560 //aWLine1->ComputeVertexParameters(theTol3D);
2562 }//if(theSlin.Length() > 0)
2565 return Standard_True;
2568 //=======================================================================
2569 //function : IntCySp
2571 //=======================================================================
2572 Standard_Boolean IntCySp(const IntSurf_Quadric& Quad1,
2573 const IntSurf_Quadric& Quad2,
2574 const Standard_Real Tol,
2575 const Standard_Boolean Reversed,
2576 Standard_Boolean& Empty,
2577 Standard_Boolean& Multpoint,
2578 IntPatch_SequenceOfLine& slin,
2579 IntPatch_SequenceOfPoint& spnt)
2584 IntSurf_TypeTrans trans1,trans2;
2585 IntAna_ResultType typint;
2586 IntPatch_Point ptsol;
2593 Cy = Quad1.Cylinder();
2594 Sp = Quad2.Sphere();
2597 Cy = Quad2.Cylinder();
2598 Sp = Quad1.Sphere();
2600 IntAna_QuadQuadGeo inter(Cy,Sp,Tol);
2602 if (!inter.IsDone()) {return Standard_False;}
2604 typint = inter.TypeInter();
2605 Standard_Integer NbSol = inter.NbSolutions();
2606 Empty = Standard_False;
2612 Empty = Standard_True;
2618 gp_Pnt psol(inter.Point(1));
2619 Standard_Real U1,V1,U2,V2;
2620 Quad1.Parameters(psol,U1,V1);
2621 Quad2.Parameters(psol,U2,V2);
2622 ptsol.SetValue(psol,Tol,Standard_True);
2623 ptsol.SetParameters(U1,V1,U2,V2);
2630 cirsol = inter.Circle(1);
2633 ElCLib::D1(0.,cirsol,ptref,Tgt);
2636 gp_Vec TestCurvature(ptref,Sp.Location());
2637 gp_Vec Normsp,Normcyl;
2639 Normcyl = Quad1.Normale(ptref);
2640 Normsp = Quad2.Normale(ptref);
2643 Normcyl = Quad2.Normale(ptref);
2644 Normsp = Quad1.Normale(ptref);
2647 IntSurf_Situation situcyl;
2648 IntSurf_Situation situsp;
2650 if (Normcyl.Dot(TestCurvature) > 0.) {
2651 situsp = IntSurf_Outside;
2652 if (Normsp.Dot(Normcyl) > 0.) {
2653 situcyl = IntSurf_Inside;
2656 situcyl = IntSurf_Outside;
2660 situsp = IntSurf_Inside;
2661 if (Normsp.Dot(Normcyl) > 0.) {
2662 situcyl = IntSurf_Outside;
2665 situcyl = IntSurf_Inside;
2668 Handle(IntPatch_GLine) glig;
2670 glig = new IntPatch_GLine(cirsol, Standard_True, situcyl, situsp);
2673 glig = new IntPatch_GLine(cirsol, Standard_True, situsp, situcyl);
2678 if (Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref)) > 0.0) {
2679 trans1 = IntSurf_Out;
2680 trans2 = IntSurf_In;
2683 trans1 = IntSurf_In;
2684 trans2 = IntSurf_Out;
2686 Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
2689 cirsol = inter.Circle(2);
2690 ElCLib::D1(0.,cirsol,ptref,Tgt);
2691 Standard_Real qwe = Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
2692 if(qwe> 0.0000001) {
2693 trans1 = IntSurf_Out;
2694 trans2 = IntSurf_In;
2696 else if(qwe<-0.0000001) {
2697 trans1 = IntSurf_In;
2698 trans2 = IntSurf_Out;
2701 trans1=trans2=IntSurf_Undecided;
2703 glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
2709 case IntAna_NoGeometricSolution:
2712 Standard_Real U1,V1,U2,V2;
2713 IntAna_IntQuadQuad anaint(Cy,Sp,Tol);
2714 if (!anaint.IsDone()) {
2715 return Standard_False;
2718 if (anaint.NbPnt()==0 && anaint.NbCurve()==0) {
2719 Empty = Standard_True;
2723 NbSol = anaint.NbPnt();
2724 for (i = 1; i <= NbSol; i++) {
2725 psol = anaint.Point(i);
2726 Quad1.Parameters(psol,U1,V1);
2727 Quad2.Parameters(psol,U2,V2);
2728 ptsol.SetValue(psol,Tol,Standard_True);
2729 ptsol.SetParameters(U1,V1,U2,V2);
2733 gp_Pnt ptvalid,ptf,ptl;
2735 Standard_Real first,last,para;
2736 IntAna_Curve curvsol;
2737 Standard_Boolean tgfound;
2738 Standard_Integer kount;
2740 NbSol = anaint.NbCurve();
2741 for (i = 1; i <= NbSol; i++) {
2742 curvsol = anaint.Curve(i);
2743 curvsol.Domain(first,last);
2744 ptf = curvsol.Value(first);
2745 ptl = curvsol.Value(last);
2749 tgfound = Standard_False;
2752 para = (1.123*first + para)/2.123;
2753 tgfound = curvsol.D1u(para,ptvalid,tgvalid);
2756 tgfound = kount > 5;
2759 Handle(IntPatch_ALine) alig;
2761 Standard_Real qwe = tgvalid.DotCross(Quad2.Normale(ptvalid),
2762 Quad1.Normale(ptvalid));
2763 if(qwe> 0.00000001) {
2764 trans1 = IntSurf_Out;
2765 trans2 = IntSurf_In;
2767 else if(qwe<-0.00000001) {
2768 trans1 = IntSurf_In;
2769 trans2 = IntSurf_Out;
2772 trans1=trans2=IntSurf_Undecided;
2774 alig = new IntPatch_ALine(curvsol,Standard_False,trans1,trans2);
2777 alig = new IntPatch_ALine(curvsol,Standard_False);
2779 Standard_Boolean TempFalse1a = Standard_False;
2780 Standard_Boolean TempFalse2a = Standard_False;
2782 //-- ptf et ptl : points debut et fin de alig
2784 ProcessBounds(alig,slin,Quad1,Quad2,TempFalse1a,ptf,first,
2785 TempFalse2a,ptl,last,Multpoint,Tol);
2787 } //-- boucle sur les lignes
2788 } //-- solution avec au moins une lihne
2794 return Standard_False;
2797 return Standard_True;
2799 //=======================================================================
2800 //function : IntCyCo
2802 //=======================================================================
2803 Standard_Boolean IntCyCo(const IntSurf_Quadric& Quad1,
2804 const IntSurf_Quadric& Quad2,
2805 const Standard_Real Tol,
2806 const Standard_Boolean Reversed,
2807 Standard_Boolean& Empty,
2808 Standard_Boolean& Multpoint,
2809 IntPatch_SequenceOfLine& slin,
2810 IntPatch_SequenceOfPoint& spnt)
2813 IntPatch_Point ptsol;
2817 IntSurf_TypeTrans trans1,trans2;
2818 IntAna_ResultType typint;
2825 Cy = Quad1.Cylinder();
2829 Cy = Quad2.Cylinder();
2832 IntAna_QuadQuadGeo inter(Cy,Co,Tol);
2834 if (!inter.IsDone()) {return Standard_False;}
2836 typint = inter.TypeInter();
2837 Standard_Integer NbSol = inter.NbSolutions();
2838 Empty = Standard_False;
2842 case IntAna_Empty : {
2843 Empty = Standard_True;
2847 case IntAna_Point :{
2848 gp_Pnt psol(inter.Point(1));
2849 Standard_Real U1,V1,U2,V2;
2850 Quad1.Parameters(psol,U1,V1);
2851 Quad1.Parameters(psol,U2,V2);
2852 ptsol.SetValue(psol,Tol,Standard_True);
2853 ptsol.SetParameters(U1,V1,U2,V2);
2858 case IntAna_Circle: {
2864 for(j=1; j<=2; ++j) {
2865 cirsol = inter.Circle(j);
2866 ElCLib::D1(0.,cirsol,ptref,Tgt);
2867 qwe = Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
2868 if(qwe> 0.00000001) {
2869 trans1 = IntSurf_Out;
2870 trans2 = IntSurf_In;
2872 else if(qwe<-0.00000001) {
2873 trans1 = IntSurf_In;
2874 trans2 = IntSurf_Out;
2877 trans1=trans2=IntSurf_Undecided;
2879 Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
2885 case IntAna_NoGeometricSolution: {
2887 Standard_Real U1,V1,U2,V2;
2888 IntAna_IntQuadQuad anaint(Cy,Co,Tol);
2889 if (!anaint.IsDone()) {
2890 return Standard_False;
2893 if (anaint.NbPnt() == 0 && anaint.NbCurve() == 0) {
2894 Empty = Standard_True;
2897 NbSol = anaint.NbPnt();
2898 for (i = 1; i <= NbSol; i++) {
2899 psol = anaint.Point(i);
2900 Quad1.Parameters(psol,U1,V1);
2901 Quad2.Parameters(psol,U2,V2);
2902 ptsol.SetValue(psol,Tol,Standard_True);
2903 ptsol.SetParameters(U1,V1,U2,V2);
2907 gp_Pnt ptvalid, ptf, ptl;
2910 Standard_Real first,last,para;
2911 Standard_Boolean tgfound,firstp,lastp,kept;
2912 Standard_Integer kount;
2915 //IntAna_Curve curvsol;
2917 IntAna_ListOfCurve aLC;
2918 IntAna_ListIteratorOfListOfCurve aIt;
2921 NbSol = anaint.NbCurve();
2922 for (i = 1; i <= NbSol; ++i) {
2923 kept = Standard_False;
2924 //curvsol = anaint.Curve(i);
2927 ExploreCurve(Cy, Co, aC, 10.*Tol, aLC);
2929 aIt.Initialize(aLC);
2930 for (; aIt.More(); aIt.Next()) {
2931 IntAna_Curve& curvsol=aIt.Value();
2933 curvsol.Domain(first, last);
2934 firstp = !curvsol.IsFirstOpen();
2935 lastp = !curvsol.IsLastOpen();
2937 ptf = curvsol.Value(first);
2940 ptl = curvsol.Value(last);
2944 tgfound = Standard_False;
2947 para = (1.123*first + para)/2.123;
2948 tgfound = curvsol.D1u(para,ptvalid,tgvalid);
2951 tgfound = kount > 5;
2954 Handle(IntPatch_ALine) alig;
2956 Standard_Real qwe = tgvalid.DotCross(Quad2.Normale(ptvalid),
2957 Quad1.Normale(ptvalid));
2958 if(qwe> 0.00000001) {
2959 trans1 = IntSurf_Out;
2960 trans2 = IntSurf_In;
2962 else if(qwe<-0.00000001) {
2963 trans1 = IntSurf_In;
2964 trans2 = IntSurf_Out;
2967 trans1=trans2=IntSurf_Undecided;
2969 alig = new IntPatch_ALine(curvsol,Standard_False,trans1,trans2);
2970 kept = Standard_True;
2973 ptvalid = curvsol.Value(para);
2974 alig = new IntPatch_ALine(curvsol,Standard_False);
2975 kept = Standard_True;
2976 //-- cout << "Transition indeterminee" << endl;
2979 Standard_Boolean Nfirstp = !firstp;
2980 Standard_Boolean Nlastp = !lastp;
2981 ProcessBounds(alig,slin,Quad1,Quad2,Nfirstp,ptf,first,
2982 Nlastp,ptl,last,Multpoint,Tol);
2985 } // for (; aIt.More(); aIt.Next())
2986 } // for (i = 1; i <= NbSol; ++i)
2992 return Standard_False;
2994 } // switch (typint)
2996 return Standard_True;
2998 //=======================================================================
2999 //function : ExploreCurve
3001 //=======================================================================
3002 Standard_Boolean ExploreCurve(const gp_Cylinder& ,//aCy,
3005 const Standard_Real aTol,
3006 IntAna_ListOfCurve& aLC)
3009 Standard_Boolean bFind=Standard_False;
3010 Standard_Real aTheta, aT1, aT2, aDst;
3020 aC.Domain(aT1, aT2);
3023 aDst=aPx.Distance(aPapx);
3028 aDst=aPx.Distance(aPapx);
3033 bFind=aC.FindParameter(aPapx, aTheta);
3038 aPx=aC.Value(aTheta);
3039 aDst=aPx.Distance(aPapx);
3044 // need to be splitted at aTheta
3045 IntAna_Curve aC1, aC2;
3048 aC1.SetDomain(aT1, aTheta);
3050 aC2.SetDomain(aTheta, aT2);
3058 //=======================================================================
3059 //function : IsToReverse
3061 //=======================================================================
3062 Standard_Boolean IsToReverse(const gp_Cylinder& Cy1,
3063 const gp_Cylinder& Cy2,
3064 const Standard_Real Tol)
3066 Standard_Boolean bRet;
3067 Standard_Real aR1,aR2, dR, aSc1, aSc2;
3069 bRet=Standard_False;
3081 gp_Dir aDZ(0.,0.,1.);
3083 const gp_Dir& aDir1=Cy1.Axis().Direction();
3089 const gp_Dir& aDir2=Cy2.Axis().Direction();