1 // Created on: 1993-11-26
2 // Created by: Modelistation
3 // Copyright (c) 1993-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
9 // under the terms of the GNU Lesser General Public 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 <IntPatch_ALineToWLine.ixx>
19 #include <IntSurf_LineOn2S.hxx>
20 #include <IntSurf_PntOn2S.hxx>
21 #include <IntSurf_TypeTrans.hxx>
22 #include <IntSurf_Situation.hxx>
24 #include <TColStd_Array1OfReal.hxx>
25 #include <TColStd_Array1OfInteger.hxx>
27 #include <Precision.hxx>
32 #include <Adaptor2d_HCurve2d.hxx>
33 #include <GeomAbs_SurfaceType.hxx>
34 #include <gp_Pnt2d.hxx>
35 #include <gp_Vec2d.hxx>
36 #include <IntAna2d_AnaIntersection.hxx>
37 #include <gp_Lin2d.hxx>
38 #include <IntAna2d_IntPoint.hxx>
39 #include <gp_Cone.hxx>
43 gp_Pnt DefineDU(const Handle(IntPatch_ALine)& aline,
44 const Standard_Real U,
46 const Standard_Real CurvDef,
47 const Standard_Real AngDef);
50 Standard_Boolean SameCurve(const Handle_Adaptor2d_HCurve2d& C1,
51 const Handle_Adaptor2d_HCurve2d& C2);
54 void RecadreMemePeriode(const IntSurf_Quadric aQuad1,
55 const IntSurf_Quadric aQuad2,
58 const Standard_Real anu1,
59 const Standard_Real anu2);
62 void CorrectFirstPartOfLine(Handle(IntSurf_LineOn2S)& LinOn2S,
63 const IntSurf_Quadric aQuad1,
64 const IntSurf_Quadric aQuad2,
65 const Standard_Real ref_u1,
66 const Standard_Real ref_u2,
67 Standard_Real& new_u1,
68 Standard_Real& new_u2);
72 void RefineParameters(const Handle(IntPatch_ALine)& aALine,
73 const Standard_Real aTb,
74 const Standard_Real aTe,
75 const Standard_Real aTx,
76 const Standard_Integer iDir,
77 const IntSurf_Quadric& aQuadric,
78 const Standard_Real aTol3D,
82 Standard_Boolean FindNearParameter(const Handle(IntPatch_ALine)& aALine,
83 const Standard_Real aTx,
84 const Standard_Integer iDir,
85 const Standard_Real aTol3D,
88 Standard_Boolean IsApex(const IntSurf_Quadric& aQuadric,
89 const Standard_Real aVx,
90 const Standard_Real aTol3D);
93 //-- Je ne sais pas faire mieux et ca m'ennerve. lbr.
94 //=======================================================================
95 //function : IntPatch_ALineToWLine
97 //=======================================================================
98 IntPatch_ALineToWLine::IntPatch_ALineToWLine(const IntSurf_Quadric& Quad1,
99 const IntSurf_Quadric& Quad2)
107 myTolOpenDomain(1.e-9),
108 myTolTransition(1.e-8)
110 myTol3D=Precision::Confusion();
112 //=======================================================================
113 //function : IntPatch_ALineToWLine
115 //=======================================================================
116 IntPatch_ALineToWLine::IntPatch_ALineToWLine(const IntSurf_Quadric& Quad1,
117 const IntSurf_Quadric& Quad2,
118 const Standard_Real Deflection,
119 const Standard_Real ,
120 const Standard_Integer NbMaxPoints)
124 deflectionmax(Deflection),
125 nbpointsmax(NbMaxPoints),
127 myTolOpenDomain(1.e-9),
128 myTolTransition(1.e-8)
130 myTol3D=Precision::Confusion();
133 //=======================================================================
134 //function : SetTol3D
136 //=======================================================================
137 void IntPatch_ALineToWLine::SetTol3D(const Standard_Real aTol)
141 //=======================================================================
144 //=======================================================================
145 Standard_Real IntPatch_ALineToWLine::Tol3D()const
149 //=======================================================================
150 //function : SetTolTransition
152 //=======================================================================
153 void IntPatch_ALineToWLine::SetTolTransition(const Standard_Real aTol)
155 myTolTransition = aTol;
157 //=======================================================================
158 //function : TolTransition
160 //=======================================================================
161 Standard_Real IntPatch_ALineToWLine::TolTransition()const
163 return myTolTransition;
165 //=======================================================================
166 //function : SetTolParam
168 //=======================================================================
169 void IntPatch_ALineToWLine::SetTolParam(const Standard_Real aTolParam)
171 myTolParam = aTolParam;
173 //=======================================================================
174 //function : TolParam
176 //=======================================================================
177 Standard_Real IntPatch_ALineToWLine::TolParam()const
181 //=======================================================================
182 //function : SetTolOpenDomain
184 //=======================================================================
185 void IntPatch_ALineToWLine::SetTolOpenDomain(const Standard_Real aTol)
187 myTolOpenDomain = aTol;
189 //=======================================================================
190 //function : TolOpenDomain
192 //=======================================================================
193 Standard_Real IntPatch_ALineToWLine::TolOpenDomain()const
195 return myTolOpenDomain;
197 //=======================================================================
198 //function : SetConstantParameter
200 //=======================================================================
201 void IntPatch_ALineToWLine::SetConstantParameter() const
204 //=======================================================================
205 //function : SetUniformAbscissa
207 //=======================================================================
208 void IntPatch_ALineToWLine::SetUniformAbscissa() const
211 //=======================================================================
212 //function : SetUniformDeflection
214 //=======================================================================
215 void IntPatch_ALineToWLine::SetUniformDeflection() const
218 //=======================================================================
219 //function : MakeWLine
221 //=======================================================================
222 Handle(IntPatch_WLine) IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& aline) const
224 Standard_Boolean included;
225 Standard_Real f = aline->FirstParameter(included);
229 Standard_Real l = aline->LastParameter(included);
233 return(MakeWLine(aline,f,l));
236 //=======================================================================
237 //function : MakeWLine
239 //=======================================================================
240 Handle(IntPatch_WLine) IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& aline,
241 const Standard_Real _firstparam,
242 const Standard_Real _lastparam) const
245 Standard_Real dl, dumin, dumax, U, pv, pu1, pv1, pu2, pv2;
246 Standard_Real firstparam, lastparam;
247 Standard_Integer v, nbvtx;
248 Standard_Boolean TriOk;
250 firstparam = _firstparam;
251 lastparam = _lastparam;
253 // nbpointsmax It is the field. ( =200. by default)
254 dl = (lastparam - firstparam)/(Standard_Real)(nbpointsmax-1);
258 nbvtx = aline->NbVertex();
260 TColStd_Array1OfReal paramvertex(1,Max(nbvtx,1)), newparamvertex(1,Max(nbvtx,1));
262 for(v = 1; v<=nbvtx; v++) {
263 const IntPatch_Point& aVtx = aline->Vertex(v);
264 pv=aVtx.ParameterOnLine();
266 newparamvertex(v)=-1.;
269 //-- Tri et Confusion des vertex proches
271 TriOk = Standard_True;
272 for(v=2; v<=nbvtx;v++) {
273 if(paramvertex(v) < paramvertex(v-1)) {
275 paramvertex(v-1)=paramvertex(v);
277 TriOk = Standard_False;
283 for(v=2; v<=nbvtx;v++) {
285 pv1=paramvertex(v-1);
286 if(pv-pv1 < myTolParam) {
291 Standard_Integer t, nbpwline;
292 Standard_Real u1,v1,u2,v2, anu1, anv1, anu2, anv2;
293 Standard_Real aL, dl_sur_2;
294 gp_Pnt Pnt3d, aPnt3d1;
295 IntSurf_PntOn2S POn2S;
296 Handle(IntSurf_LineOn2S) LinOn2S;
298 LinOn2S = new IntSurf_LineOn2S;
300 //// Modified by jgv, 17.09.09 for OCC21255 ////
301 Standard_Real refpar = RealLast(), ref_u1 = 0., ref_u2 = 0.;
304 const IntPatch_Point& FirstVertex = aline->Vertex(1);
305 refpar = FirstVertex.ParameterOnLine();
306 FirstVertex.Parameters(ref_u1, v1, ref_u2, v2);
308 ////////////////////////////////////////////////
310 //-----------------------------------------------------
311 //-- Estimation Grossiere de la longueur de la courbe
315 Pnt3d = aline->Value(firstparam);
316 for(t=0, U=firstparam+dumin; U<lastparam; t++,U+=dl_sur_2) {
317 aPnt3d1 = aline->Value(U);
318 aL+=Pnt3d.Distance(aPnt3d1);
321 //------------------------------------------------------
324 //------------------------------------------------------
325 //-- Calcul du premier point
327 //------------------------------------------------------
328 //-- On reajuste firstparam et lastparam au cas ou ces
329 //-- valeurs sont tres proches des parametres de vertex
331 Standard_Real pvtxmin, pvtxmax;
333 pvtxmin = aline->Vertex(1).ParameterOnLine();
336 for(v=2; v<=nbvtx; v++) {
337 pv=aline->Vertex(v).ParameterOnLine();
345 if(Abs(pvtxmin-firstparam)<myTolOpenDomain) {
348 if(Abs(pvtxmax-lastparam)<myTolOpenDomain) {
354 Pnt3d = aline->Value(firstparam);
355 quad1.Parameters(Pnt3d,u1,v1);
357 RefineParameters(aline, firstparam, lastparam, firstparam, 1, quad1, 10.*myTol3D, u1,v1);
360 quad2.Parameters(Pnt3d,u2,v2);
362 RefineParameters(aline, firstparam, lastparam, firstparam, 1, quad2, 10.*myTol3D, u2,v2);
365 POn2S.SetValue(Pnt3d,u1,v1,u2,v2);
371 //-------------------------------------------------------
372 //-- On detecte le cas : Point de debut == vertex
373 //-- On affecte un parametre bidon qui sera recadre
374 //-- dans l insertion des vertex dans la ligne
376 for(v=1;v<=nbvtx;v++) {
377 if(newparamvertex(v)<0.) {
379 if((pv>=U-2.0*myTolOpenDomain) && (pv<=U+2.0*myTolOpenDomain)) {
380 if(pv-U > myTolParam) {
381 newparamvertex(v) = 1.000001;
383 else if(U-pv>myTolParam) {
384 newparamvertex(v) = 0.999999;
390 Standard_Real DeltaU;
394 //// Modified by jgv, 17.09.09 for OCC21255 ////
395 Standard_Boolean Corrected = Standard_False;
396 ////////////////////////////////////////////////
398 Standard_Integer NbCalculD1;
399 Standard_Real UPourCalculD1, pvavant, pvapres;
400 gp_Vec VPourCalculD1;
401 gp_Pnt PPourCalculD1;
407 if(aline->D1(UPourCalculD1,PPourCalculD1,VPourCalculD1)) {
408 Standard_Real NormV = VPourCalculD1.Magnitude();
409 if(NormV > 1.0e-16) {
415 else if (DeltaU > dumax)
417 UPourCalculD1+=dumin;
419 while((++NbCalculD1<10)&&(DeltaU==0.));
423 Standard_Real CurvDef = deflectionmax, AngDef = CurvDef;
424 if(U+DeltaU < lastparam) {
425 DefineDU(aline,U,DeltaU,CurvDef,AngDef);
430 DeltaU = (dumin+dumax)*0.5;
432 //--------------------------------------------------------
433 //-- On cherche a placer un minimum de ??? Points entre
435 //--------------------------------------------------------
436 pvavant = firstparam;
438 for(v=1;v<=nbvtx;v++) {
440 if(pv-U > myTolParam) {
446 if(U-pv > myTolParam) {
454 if(pvapres < (10.*DeltaU)) {
455 if(pvapres > (10.*dumin)) {
456 DeltaU = pvapres*0.1;
463 if (nbpwline==1 && nbvtx) {
464 Standard_Real aUnext;
469 DeltaU=0.5*(pv-firstparam);
473 //--------------------------------------------------------
474 //-- Calcul des nouveaux parametres sur les vertex
476 for(v=1;v<=nbvtx;v++) {
477 if(newparamvertex(v)<0.) {
479 if(pv>=U && pv<(U+DeltaU) && (U+DeltaU<lastparam) ) {
480 newparamvertex(v) = (Standard_Real)nbpwline + (pv-U)/DeltaU;
485 //// Modified by jgv, 17.09.09 for OCC21255 ////
486 if (!Corrected && U >= refpar)
488 CorrectFirstPartOfLine(LinOn2S, quad1, quad2, ref_u1, ref_u2, anu1, anu2);
489 Corrected = Standard_True;
491 ////////////////////////////////////////////////
495 Pnt3d = aline->Value(U);
496 quad1.Parameters(Pnt3d,u1,v1);
497 quad2.Parameters(Pnt3d,u2,v2);
498 RecadreMemePeriode(quad1, quad2, u1,u2,anu1,anu2);
501 POn2S.SetValue(Pnt3d,u1,v1,u2,v2);
504 }//while(U<lastparam)
507 for(v=1;v<=nbvtx;v++) {
508 if(newparamvertex(v)<0.) {
510 if(pv <= lastparam+myTolOpenDomain) {
512 newparamvertex(v) = (Standard_Real)nbpwline+(pv-U)/(lastparam-U);
515 newparamvertex(v) = nbpwline+1;
521 Pnt3d = aline->Value(lastparam);
522 quad1.Parameters(Pnt3d,u1,v1);
524 RefineParameters(aline, firstparam, lastparam, lastparam, -1, quad1, 10.*myTol3D, u1,v1);
526 quad2.Parameters(Pnt3d,u2,v2);
528 RefineParameters(aline, firstparam, lastparam, lastparam, -1, quad2, 10.*myTol3D, u2,v2);
530 RecadreMemePeriode(quad1, quad2, u1,u2,anu1,anu2);
531 POn2S.SetValue(Pnt3d,u1,v1,u2,v2);
535 //// Modified by jgv, 17.09.09 for OCC21255 ////
537 (lastparam >= refpar || refpar-lastparam < Precision::Confusion()))
538 CorrectFirstPartOfLine(LinOn2S, quad1, quad2, ref_u1, ref_u2, anu1, anu2);
539 ////////////////////////////////////////////////
542 //-----------------------------------------------------------------
543 //-- Calcul de la transition de la ligne sur les surfaces ---
544 //-----------------------------------------------------------------
545 IntSurf_TypeTrans trans1,trans2;
546 Standard_Integer indice1;
547 Standard_Real dotcross;
550 trans1=IntSurf_Undecided;
551 trans2=IntSurf_Undecided;
553 indice1 = nbpwline/3;
558 aPP1=LinOn2S->Value(indice1).Value();
559 aPP0=LinOn2S->Value(indice1-1).Value();
561 gp_Vec tgvalid(aPP0, aPP1);
562 gp_Vec aNQ1=quad1.Normale(aPP0);
563 gp_Vec aNQ2=quad2.Normale(aPP0);
565 dotcross = tgvalid.DotCross(aNQ2, aNQ1);
566 if (dotcross > myTolTransition) {
567 trans1 = IntSurf_Out;
570 else if(dotcross < -myTolTransition) {
572 trans2 = IntSurf_Out;
574 //-----------------------------------------------------------------
575 //-- C r e a t i o n d e la W L i n e ---
576 //-----------------------------------------------------------------
577 Handle(IntPatch_WLine) wline;
579 if(aline->TransitionOnS1() == IntSurf_Touch) {
580 Handle(IntPatch_WLine) wlinetemp = new IntPatch_WLine(LinOn2S,
582 aline->SituationS1(),
583 aline->SituationS2());
586 if(aline->TransitionOnS1() == IntSurf_Undecided) {
587 Handle(IntPatch_WLine) wlinetemp = new IntPatch_WLine(LinOn2S,
592 Handle(IntPatch_WLine) wlinetemp = new IntPatch_WLine(LinOn2S,
594 trans1, // aline->TransitionOnS1(),
595 trans2); //aline->TransitionOnS2());
599 //-----------------------------------------------------------------
600 //-- I n s e r t i o n d e s v e r t e x ---
601 //-----------------------------------------------------------------
602 TColStd_Array1OfInteger Redir(1,Max(nbvtx,1));
604 for(v=1;v<=nbvtx;v++) {
609 Standard_Integer tamp;
611 TriOk = Standard_True;
612 for(v=2; v<=nbvtx;v++) {
613 if(newparamvertex(Redir(v))<newparamvertex(Redir(v-1))) {
615 Redir(v-1) = Redir(v);
617 TriOk = Standard_False;
623 //-----------------------------------------------------------------
624 //-- On detecte le cas ou un Vtx de param 1 ou nbpwline OnArc est double
625 //-- Dans ce cas on supprime le vertex qui reference un arc deja reference
626 //-- par un autre vertex
627 //nbvtx = aline->NbVertex();
628 Standard_Boolean APointHasBeenRemoved;
631 Standard_Boolean RemoveVtxo, RemoveVtx;
632 Standard_Integer vo, voo;
633 Standard_Real ponl, ponlo, ponloo, aDist13, aDist23;
635 APointHasBeenRemoved = Standard_False;
636 RemoveVtxo = Standard_False;
637 RemoveVtx = Standard_False;
639 for(v=1; v<=nbvtx && !APointHasBeenRemoved; v++) {
641 if(newparamvertex(v)>=0.) {
642 const IntPatch_Point& Vtx = aline->Vertex(v);
643 ponl = Vtx.ParameterOnLine();
644 const gp_Pnt& aP=Vtx.Value();
646 for(vo=1; vo<=nbvtx && !APointHasBeenRemoved; vo++) {
648 if(newparamvertex(vo)>=0.) {
649 const IntPatch_Point& Vtxo = aline->Vertex(vo);
650 ponlo = Vtxo.ParameterOnLine();
651 const gp_Pnt& aPo=Vtxo.Value();
653 if(ponl-ponlo<myTolParam && ponlo-ponl<myTolParam) {
655 for(voo=1; voo<=nbvtx && !APointHasBeenRemoved; voo++) {
656 if(voo!=v && voo!=vo) {
657 if(newparamvertex(voo)>=0.) {
658 const IntPatch_Point& Vtxoo = aline->Vertex(voo);
659 ponloo = Vtxoo.ParameterOnLine();
660 const gp_Pnt& aPoo=Vtxoo.Value();
662 aDist13=aP.Distance(aPoo);
664 if(aDist13<=myTol3D) {
665 //-- 2 vertex de meme param + un confondu geometriquement
666 if((Vtx.IsOnDomS1() == Vtxoo.IsOnDomS1()) &&
667 (Vtx.IsOnDomS2() == Vtxoo.IsOnDomS2()) ) {
669 if(Vtx.IsOnDomS1()) {
670 if(Vtx.ParameterOnArc1()==Vtxoo.ParameterOnArc1()) {
671 if(SameCurve(Vtxoo.ArcOnS1(),Vtx.ArcOnS1())) { //-- param on s1 ?
672 RemoveVtx = Standard_True;
676 if(Vtx.IsOnDomS2()) {
677 if(Vtx.ParameterOnArc2()==Vtxoo.ParameterOnArc2()) {
678 if(SameCurve(Vtxoo.ArcOnS2(),Vtx.ArcOnS2())) {
679 RemoveVtx = Standard_True;
683 RemoveVtx = Standard_False;
688 if(RemoveVtx==Standard_False) {
690 aDist23=aPo.Distance(aPoo);
692 if(aDist23<=myTol3D) {
693 //-- 2 vertex de meme param + un confondu geometriquement
694 if((Vtxo.IsOnDomS1() == Vtxoo.IsOnDomS1())&&
695 (Vtxo.IsOnDomS2() == Vtxoo.IsOnDomS2()) ) {
696 if(Vtxo.IsOnDomS1()) {
697 if(Vtxo.ParameterOnArc1()==Vtxoo.ParameterOnArc1()) {
698 if(SameCurve(Vtxoo.ArcOnS1(),Vtxo.ArcOnS1())) { //-- param on s1 ?
699 RemoveVtxo = Standard_True;
703 if(Vtxo.IsOnDomS2()) {
704 if(Vtxo.ParameterOnArc2()==Vtxoo.ParameterOnArc2()) {
705 if(SameCurve(Vtxoo.ArcOnS2(),Vtxo.ArcOnS2())) {
706 RemoveVtxo = Standard_True;
710 RemoveVtxo = Standard_False;
717 newparamvertex(v) = -1.;
718 APointHasBeenRemoved = Standard_True;
720 else if(RemoveVtxo) {
721 newparamvertex(vo) = -1.;
722 APointHasBeenRemoved = Standard_True;
725 } //-- voo!=v && voo!=vo
726 } //-- Fin boucle sur voo
733 }//for(v=1; v<=nbvtx && !APointHasBeenRemoved; v++)
735 while(APointHasBeenRemoved);
737 Standard_Integer ParamVtxPrecedent, refpointonwline, aIndV;
738 Standard_Real pvtx, approxparamonwline, aDst;
739 Standard_Boolean bIsApex1, bIsApex2;
741 ParamVtxPrecedent = 0;
743 for(v=1; v<=nbvtx; v++) {
745 pv=paramvertex(v);// parameter from ALine
746 pvtx = newparamvertex(aIndV);
747 if(pvtx>=0. && (pvtx <= nbpwline+1)) {
748 approxparamonwline=newparamvertex(aIndV);
751 IntPatch_Point NewPoint = aline->Vertex(aIndV);
753 Pnt3d = NewPoint.Value();
754 quad1.Parameters(Pnt3d, u1, v1);
755 quad2.Parameters(Pnt3d, u2, v2);
756 //-------------------------------------------------------
757 //-- On recadre les parametres des vertex dans la bonne -
758 //-- periode en recadrant avec le point le plus proche -
759 //-------------------------------------------------------
760 if(approxparamonwline > nbpwline) {
761 refpointonwline = nbpwline-1;
763 else if(approxparamonwline < 1) {
767 refpointonwline = (Standard_Integer)approxparamonwline;
771 const IntSurf_PntOn2S& aP2Sx=LinOn2S->Value(refpointonwline);
772 aP2Sx.ParametersOnS1(anu1, anv1);
773 aP2Sx.ParametersOnS2(anu2, anv2);
775 bIsApex1=IsApex(quad1, v1, myTol3D);
776 bIsApex2=IsApex(quad2, v2, myTol3D);
778 //if (refpointonwline==1 || refpointonwline==nbpwline) {
779 if (bIsApex1 || bIsApex2) {
780 if (fabs(pv-firstparam)<myTolParam || fabs(pv-lastparam)<myTolParam) {
781 // aline starts(ends) on vertex
782 const gp_Pnt& aP1x=aP2Sx.Value();
784 aDst=aP1x.Distance(Pnt3d);
785 if (aDst<10.*myTol3D) {
794 // aline goes through vertex
806 ParamVtxPrecedent=refpointonwline;
807 RecadreMemePeriode(quad1, quad2, u1,u2,anu1,anu2);
808 NewPoint.SetParameter(refpointonwline);
810 NewPoint.SetParameters(u1,v1,u2,v2);
811 wline->AddVertex(NewPoint);
815 if(ParamVtxPrecedent==refpointonwline) {
816 //-- 2 vertex renseignent le meme point de la LineOn2S
817 //-- On insere un nv point = vtx
818 //-- On decale tous les vtx apres de 1
819 RecadreMemePeriode(quad1, quad2, u1,u2,anu1,anu2);
820 POn2S.SetValue(Pnt3d,u1,v1,u2,v2);
821 LinOn2S->InsertBefore(refpointonwline+1, POn2S);
823 NewPoint.SetParameter(refpointonwline+1);
824 NewPoint.SetParameters(u1,v1,u2,v2);
825 wline->AddVertex(NewPoint);
826 ParamVtxPrecedent = refpointonwline+1;
828 Standard_Integer vv=v+1;
829 for(; vv<=nbvtx; vv++) {
830 if(newparamvertex(Redir(vv))!=-1.) {
831 newparamvertex(Redir(vv))=newparamvertex(Redir(vv))+1.;
837 RecadreMemePeriode(quad1, quad2, u1,u2, anu1, anu2);
838 NewPoint.SetParameter(refpointonwline);
840 NewPoint.SetParameters(u1, v1, u2, v2);
841 wline->AddVertex(NewPoint);
842 ParamVtxPrecedent = refpointonwline;
853 switch(quad1.TypeQuadric()) {
854 case GeomAbs_Cylinder:
865 switch(quad2.TypeQuadric()) {
866 case GeomAbs_Cylinder:
877 wline->SetPeriod(pu1,pv1,pu2,pv2);
879 wline->ComputeVertexParameters(myTol3D);
882 //=======================================================================
883 //function : DefineDU
885 //=======================================================================
886 gp_Pnt DefineDU(const Handle(IntPatch_ALine)& aline,
887 const Standard_Real U,
889 const Standard_Real CurvDef,
890 const Standard_Real AngDef)
892 gp_Pnt P1 = aline->Value(U), P2, P3;
893 gp_Vec V13, V12, V23;
894 Standard_Real dU = DU/2.0, curvDef, angDef, m1, m2, m3;
895 for(;;) { //According to class TangentialDeflection from GCPnts
896 P2=aline->Value(U+dU); P3=aline->Value(U+DU);
897 V13 = P3.XYZ().Subtracted(P1.XYZ()); m1 = V13.Magnitude();
898 V12 = P2.XYZ().Subtracted(P1.XYZ()); m2 = V12.Magnitude();
899 V23 = P3.XYZ().Subtracted(P2.XYZ()); m3 = V23.Magnitude();
900 if(m1 < CurvDef || m2 < CurvDef || m3 < CurvDef) break;
901 curvDef = Abs(V13.Angle(V12));
902 angDef = Abs(V13.Angle(V23));
903 if(curvDef < CurvDef && angDef < AngDef) break;
908 //=======================================================================
909 //function : SameCurve
911 //=======================================================================
912 Standard_Boolean SameCurve(const Handle_Adaptor2d_HCurve2d& C1,const Handle_Adaptor2d_HCurve2d& C2)
914 Standard_Real C1f = C1->FirstParameter();
915 Standard_Real C2f = C2->FirstParameter();
916 if(C1f!=C2f) return(Standard_False);
917 Standard_Real C1l = C1->LastParameter();
918 Standard_Real C2l = C2->LastParameter();
919 if(C1l!=C2l) return(Standard_False);
920 Standard_Real u=0.3*C1f+0.7*C1l;
921 gp_Pnt2d P1 = C1->Value(u);
922 gp_Pnt2d P2 = C2->Value(u);
923 if(P1.X()!=P2.X()) return(Standard_False);
924 if(P1.Y()!=P2.Y()) return(Standard_False);
925 return(Standard_True);
927 //=======================================================================
928 //function : RecadreMemePeriode
930 //=======================================================================
931 void RecadreMemePeriode(const IntSurf_Quadric aQuad1,
932 const IntSurf_Quadric aQuad2,
935 const Standard_Real anu1,
936 const Standard_Real anu2)
938 Standard_Boolean bBothCylinders;
939 GeomAbs_SurfaceType aType1, aType2;
941 aType1=aQuad1.TypeQuadric();
942 aType2=aQuad2.TypeQuadric();
943 bBothCylinders=(aType1==GeomAbs_Cylinder && aType2==GeomAbs_Cylinder);
945 while(anu1-u1 > 5.0) {
948 while(u1-anu1 > 5.0) {
951 if (!bBothCylinders) {//cfe900/H6
952 // this check on Cylinder/Cylinder intersection is probably
953 // because of pbs with ALine on it.
954 // For other Quadrics there was no pbs found during
956 // (it is necessary to see ...IntCyCy(...) for details).
958 // In any case the pb does not deal with apex problem.
960 if (u1-M_PI-M_PI<0.) {
968 while(anu2-u2 > 5.0) {
971 while(u2-anu2 > 5.0) {
974 if (!bBothCylinders) {//cfe900/H6
975 if (u2-M_PI-M_PI<0.) {
985 //=======================================================================
986 //function : CorrectFirstPartOfLine
988 //=======================================================================
989 void CorrectFirstPartOfLine(Handle(IntSurf_LineOn2S)& LinOn2S,
990 const IntSurf_Quadric aQuad1,
991 const IntSurf_Quadric aQuad2,
992 const Standard_Real ref_u1,
993 const Standard_Real ref_u2,
994 Standard_Real& new_u1,
995 Standard_Real& new_u2)
997 Standard_Integer nbp = LinOn2S->NbPoints();
998 Standard_Real u1, v1, u2, v2, OffsetOnS1, OffsetOnS2;
1000 IntSurf_PntOn2S aPoint = LinOn2S->Value(nbp);
1001 aPoint.Parameters(u1, v1, u2, v2);
1005 RecadreMemePeriode(aQuad1, aQuad2, new_u1, new_u2, ref_u1, ref_u2);
1006 OffsetOnS1 = new_u1 - u1;
1007 OffsetOnS2 = new_u2 - u2;
1008 if (Abs(OffsetOnS1) > 1. || Abs(OffsetOnS2) > 1.) //recadre on n*2*PI is done
1011 for (i = 1; i <= nbp; i++)
1013 aPoint = LinOn2S->Value(i);
1014 aPoint.Parameters(u1, v1, u2, v2);
1015 LinOn2S->SetUV( i, Standard_True, u1 + OffsetOnS1, v1 );
1016 LinOn2S->SetUV( i, Standard_False, u2 + OffsetOnS2, v2 );
1022 //=======================================================================
1025 //=======================================================================
1026 Standard_Boolean IsApex(const IntSurf_Quadric& aQuadric,
1027 const Standard_Real aVx,
1028 const Standard_Real aTol3D)
1031 Standard_Boolean bFlag;
1032 Standard_Real aHalfPi, aEpsilon;
1033 GeomAbs_SurfaceType aType;
1035 bFlag=Standard_False;
1037 aType=aQuadric.TypeQuadric();
1038 if (!(aType==GeomAbs_Cone || aType==GeomAbs_Sphere)) {
1042 aEpsilon=Epsilon(10.);//1.77e-15
1044 // apex on the Sphere
1045 if(aType==GeomAbs_Sphere) {
1047 if (fabs(aVx-aHalfPi)<aEpsilon) {
1050 else if (fabs(aVx+aHalfPi)<aEpsilon){
1056 else if(aType==GeomAbs_Cone) {
1061 aCone=aQuadric.Cone();
1063 aPx=aQuadric.Value(0.,aVx);
1065 aDst=aPx.Distance(aPap);
1072 //=======================================================================
1073 //function : RefineParameters
1075 //=======================================================================
1076 void RefineParameters(const Handle(IntPatch_ALine)& aALine,
1077 const Standard_Real aTb,
1078 const Standard_Real aTe,
1079 const Standard_Real aTx,
1080 const Standard_Integer iDir,
1081 const IntSurf_Quadric& aQuadric,
1082 const Standard_Real aTol3D,
1086 GeomAbs_SurfaceType aType;
1088 aType=aQuadric.TypeQuadric();
1089 if (!(aType==GeomAbs_Cone || aType==GeomAbs_Sphere)) {
1093 Standard_Boolean bIsDone, bIsEmpty, bParallel, bFound;
1094 Standard_Integer aNbPoints = 0;
1095 Standard_Real aHalfPi, aEpsilon, aLimV, dT, aT1, aT2 = 0., aEpsT;
1096 Standard_Real aU1, aV1, aU2, aV2;
1097 gp_Pnt aP1, aP2, aPx;
1098 gp_Pnt2d aP2D1, aP2D2, aPLim(0., 0.);
1099 gp_Vec2d aVLim(1., 0.);
1101 IntAna2d_AnaIntersection aAI;
1103 aEpsilon=Epsilon(10.);//1.77e-15
1105 aLLim.SetDirection(aVLim);
1108 if(aType==GeomAbs_Cone) {
1113 aCone=aQuadric.Cone();
1115 //aPx=aQuadric.Value(0.,aVx);
1116 aPx=aALine->Value(aTx);
1118 aDst=aPx.Distance(aPap);
1119 if(aDst>aTol3D) {// nothing to do
1124 aLLim.SetLocation(aPLim);
1128 // apex on the Sphere
1129 if(aType==GeomAbs_Sphere) {
1132 if (fabs(aVx-aHalfPi)<aEpsilon) {
1135 else if (fabs(aVx+aHalfPi)<aEpsilon){
1139 //Check: aUx must be 0 or 2*pi
1140 if(fabs(aUx) < aEpsilon || fabs(aUx - 2.*M_PI) < aEpsilon) {
1141 //aUx = 0 or 2*pi, but may be it must be 2*pi or 0?
1142 bFound=FindNearParameter(aALine, aTx, iDir, aTol3D, aT1);
1151 aP1=aALine->Value(aT1);
1152 aQuadric.Parameters(aP1, aU1, aV1);
1154 if(fabs(aU1) > fabs(aU1 - 2.*M_PI)) {
1166 aLLim.SetLocation(aPLim);
1171 // Try to find aT1, aT2 taking into acc 3D Tolerance
1172 bFound=FindNearParameter(aALine, aTx, iDir, aTol3D, aT1);
1174 bFound=FindNearParameter(aALine, aT1, iDir, aTol3D, aT2);
1177 // Assign aT1, aT2 by some values
1186 aP1=aALine->Value(aT1);
1187 aQuadric.Parameters(aP1, aU1, aV1);
1188 aP2D1.SetCoord(aU1, aV1);
1190 aP2=aALine->Value(aT2);
1191 aQuadric.Parameters(aP2, aU2, aV2);
1192 aP2D2.SetCoord(aU2, aV2);
1194 gp_Vec2d aV12(aP2D1, aP2D2);
1196 if(aV12.SquareMagnitude() <= aEpsilon) {
1199 gp_Lin2d aL12(aP2D1, aV12);
1201 aAI.Perform(aLLim, aL12);
1202 bIsDone=aAI.IsDone();
1206 bIsEmpty=aAI.IsEmpty();
1210 aNbPoints=aAI.NbPoints();
1214 bParallel=aAI.ParallelElements();
1218 const IntAna2d_IntPoint& aIAPnt=aAI.Point(1);
1219 const gp_Pnt2d& aP2D=aIAPnt.Value();
1222 //=======================================================================
1223 //function : FindNearParameter
1225 //=======================================================================
1226 Standard_Boolean FindNearParameter(const Handle(IntPatch_ALine)& aALine,
1227 const Standard_Real aTx,
1228 const Standard_Integer iDir,
1229 const Standard_Real aTol3D,
1232 Standard_Boolean bFound;
1233 Standard_Real aX, aY, aZ;
1239 bFound=aALine->D1(aTx, aPx, aVx);
1247 aX=aPx.X()+aDx.X()*aTol3D;
1248 aY=aPx.Y()+aDx.Y()*aTol3D;
1249 aZ=aPx.Z()+aDx.Z()*aTol3D;
1250 aP1.SetCoord(aX, aY, aZ);
1252 bFound=aALine->FindParameter(aP1, aT1);