1 // File: IntPatch_ALineToWLine.cxx
2 // Created: Fri Nov 26 10:26:11 1993
3 // Author: Modelistation
4 // Copyright: Matra Datavision 1993
6 #include <IntPatch_ALineToWLine.ixx>
8 #include <IntSurf_LineOn2S.hxx>
9 #include <IntSurf_PntOn2S.hxx>
10 #include <IntSurf_TypeTrans.hxx>
11 #include <IntSurf_Situation.hxx>
13 #include <TColStd_Array1OfReal.hxx>
14 #include <TColStd_Array1OfInteger.hxx>
16 #include <Precision.hxx>
21 #include <Adaptor2d_HCurve2d.hxx>
22 #include <GeomAbs_SurfaceType.hxx>
23 #include <gp_Pnt2d.hxx>
24 #include <gp_Vec2d.hxx>
25 #include <IntAna2d_AnaIntersection.hxx>
26 #include <gp_Lin2d.hxx>
27 #include <IntAna2d_IntPoint.hxx>
28 #include <gp_Cone.hxx>
32 gp_Pnt DefineDU(const Handle(IntPatch_ALine)& aline,
33 const Standard_Real U,
35 const Standard_Real CurvDef,
36 const Standard_Real AngDef);
39 Standard_Boolean SameCurve(const Handle_Adaptor2d_HCurve2d& C1,
40 const Handle_Adaptor2d_HCurve2d& C2);
43 void RecadreMemePeriode(const IntSurf_Quadric aQuad1,
44 const IntSurf_Quadric aQuad2,
47 const Standard_Real anu1,
48 const Standard_Real anu2);
51 void CorrectFirstPartOfLine(Handle(IntSurf_LineOn2S)& LinOn2S,
52 const IntSurf_Quadric aQuad1,
53 const IntSurf_Quadric aQuad2,
54 const Standard_Real ref_u1,
55 const Standard_Real ref_u2,
56 Standard_Real& new_u1,
57 Standard_Real& new_u2);
61 void RefineParameters(const Handle(IntPatch_ALine)& aALine,
62 const Standard_Real aTb,
63 const Standard_Real aTe,
64 const Standard_Real aTx,
65 const Standard_Integer iDir,
66 const IntSurf_Quadric& aQuadric,
67 const Standard_Real aTol3D,
71 Standard_Boolean FindNearParameter(const Handle(IntPatch_ALine)& aALine,
72 const Standard_Real aTx,
73 const Standard_Integer iDir,
74 const Standard_Real aTol3D,
77 Standard_Boolean IsApex(const IntSurf_Quadric& aQuadric,
78 const Standard_Real aVx,
79 const Standard_Real aTol3D);
82 //-- Je ne sais pas faire mieux et ca m'ennerve. lbr.
83 //=======================================================================
84 //function : IntPatch_ALineToWLine
86 //=======================================================================
87 IntPatch_ALineToWLine::IntPatch_ALineToWLine(const IntSurf_Quadric& Quad1,
88 const IntSurf_Quadric& Quad2)
97 myTolOpenDomain(1.e-9),
98 myTolTransition(1.e-8)
100 myTol3D=Precision::Confusion();
102 //=======================================================================
103 //function : IntPatch_ALineToWLine
105 //=======================================================================
106 IntPatch_ALineToWLine::IntPatch_ALineToWLine(const IntSurf_Quadric& Quad1,
107 const IntSurf_Quadric& Quad2,
108 const Standard_Real Deflection,
109 const Standard_Real PasUVMax,
110 const Standard_Integer NbMaxPoints)
114 deflectionmax(Deflection),
116 nbpointsmax(NbMaxPoints),
118 myTolOpenDomain(1.e-9),
119 myTolTransition(1.e-8)
121 myTol3D=Precision::Confusion();
124 //=======================================================================
125 //function : SetTol3D
127 //=======================================================================
128 void IntPatch_ALineToWLine::SetTol3D(const Standard_Real aTol)
132 //=======================================================================
135 //=======================================================================
136 Standard_Real IntPatch_ALineToWLine::Tol3D()const
140 //=======================================================================
141 //function : SetTolTransition
143 //=======================================================================
144 void IntPatch_ALineToWLine::SetTolTransition(const Standard_Real aTol)
146 myTolTransition = aTol;
148 //=======================================================================
149 //function : TolTransition
151 //=======================================================================
152 Standard_Real IntPatch_ALineToWLine::TolTransition()const
154 return myTolTransition;
156 //=======================================================================
157 //function : SetTolParam
159 //=======================================================================
160 void IntPatch_ALineToWLine::SetTolParam(const Standard_Real aTolParam)
162 myTolParam = aTolParam;
164 //=======================================================================
165 //function : TolParam
167 //=======================================================================
168 Standard_Real IntPatch_ALineToWLine::TolParam()const
172 //=======================================================================
173 //function : SetTolOpenDomain
175 //=======================================================================
176 void IntPatch_ALineToWLine::SetTolOpenDomain(const Standard_Real aTol)
178 myTolOpenDomain = aTol;
180 //=======================================================================
181 //function : TolOpenDomain
183 //=======================================================================
184 Standard_Real IntPatch_ALineToWLine::TolOpenDomain()const
186 return myTolOpenDomain;
188 //=======================================================================
189 //function : SetConstantParameter
191 //=======================================================================
192 void IntPatch_ALineToWLine::SetConstantParameter() const
195 //=======================================================================
196 //function : SetUniformAbscissa
198 //=======================================================================
199 void IntPatch_ALineToWLine::SetUniformAbscissa() const
202 //=======================================================================
203 //function : SetUniformDeflection
205 //=======================================================================
206 void IntPatch_ALineToWLine::SetUniformDeflection() const
209 //=======================================================================
210 //function : MakeWLine
212 //=======================================================================
213 Handle(IntPatch_WLine) IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& aline) const
215 Standard_Boolean included;
216 Standard_Real f = aline->FirstParameter(included);
220 Standard_Real l = aline->LastParameter(included);
224 return(MakeWLine(aline,f,l));
227 //=======================================================================
228 //function : MakeWLine
230 //=======================================================================
231 Handle(IntPatch_WLine) IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& aline,
232 const Standard_Real _firstparam,
233 const Standard_Real _lastparam) const
236 Standard_Real dl, dumin, dumax, U, pv, pu1, pv1, pu2, pv2;
237 Standard_Real firstparam, lastparam;
238 Standard_Integer v, nbvtx;
239 Standard_Boolean TriOk;
241 firstparam = _firstparam;
242 lastparam = _lastparam;
244 // nbpointsmax It is the field. ( =200. by default)
245 dl = (lastparam - firstparam)/(Standard_Real)(nbpointsmax-1);
249 nbvtx = aline->NbVertex();
251 TColStd_Array1OfReal paramvertex(1,Max(nbvtx,1)), newparamvertex(1,Max(nbvtx,1));
253 for(v = 1; v<=nbvtx; v++) {
254 const IntPatch_Point& aVtx = aline->Vertex(v);
255 pv=aVtx.ParameterOnLine();
257 newparamvertex(v)=-1.;
260 //-- Tri et Confusion des vertex proches
262 TriOk = Standard_True;
263 for(v=2; v<=nbvtx;v++) {
264 if(paramvertex(v) < paramvertex(v-1)) {
266 paramvertex(v-1)=paramvertex(v);
268 TriOk = Standard_False;
274 for(v=2; v<=nbvtx;v++) {
276 pv1=paramvertex(v-1);
277 if(pv-pv1 < myTolParam) {
282 Standard_Integer t, nbpwline;
283 Standard_Real u1,v1,u2,v2, anu1, anv1, anu2, anv2;
284 Standard_Real aL, dl_sur_2;
285 gp_Pnt Pnt3d, aPnt3d1;
286 IntSurf_PntOn2S POn2S;
287 Handle(IntSurf_LineOn2S) LinOn2S;
289 LinOn2S = new IntSurf_LineOn2S;
291 //// Modified by jgv, 17.09.09 for OCC21255 ////
292 Standard_Real refpar = RealLast(), ref_u1, ref_u2;
295 const IntPatch_Point& FirstVertex = aline->Vertex(1);
296 refpar = FirstVertex.ParameterOnLine();
297 FirstVertex.Parameters(ref_u1, v1, ref_u2, v2);
299 ////////////////////////////////////////////////
301 //-----------------------------------------------------
302 //-- Estimation Grossiere de la longueur de la courbe
306 Pnt3d = aline->Value(firstparam);
307 for(t=0, U=firstparam+dumin; U<lastparam; t++,U+=dl_sur_2) {
308 aPnt3d1 = aline->Value(U);
309 aL+=Pnt3d.Distance(aPnt3d1);
312 //------------------------------------------------------
315 //------------------------------------------------------
316 //-- Calcul du premier point
318 //------------------------------------------------------
319 //-- On reajuste firstparam et lastparam au cas ou ces
320 //-- valeurs sont tres proches des parametres de vertex
322 Standard_Real pvtxmin, pvtxmax;
324 pvtxmin = aline->Vertex(1).ParameterOnLine();
327 for(v=2; v<=nbvtx; v++) {
328 pv=aline->Vertex(v).ParameterOnLine();
336 if(Abs(pvtxmin-firstparam)<myTolOpenDomain) {
339 if(Abs(pvtxmax-lastparam)<myTolOpenDomain) {
345 Pnt3d = aline->Value(firstparam);
346 quad1.Parameters(Pnt3d,u1,v1);
348 RefineParameters(aline, firstparam, lastparam, firstparam, 1, quad1, 10.*myTol3D, u1,v1);
351 quad2.Parameters(Pnt3d,u2,v2);
353 RefineParameters(aline, firstparam, lastparam, firstparam, 1, quad2, 10.*myTol3D, u2,v2);
356 POn2S.SetValue(Pnt3d,u1,v1,u2,v2);
362 //-------------------------------------------------------
363 //-- On detecte le cas : Point de debut == vertex
364 //-- On affecte un parametre bidon qui sera recadre
365 //-- dans l insertion des vertex dans la ligne
367 for(v=1;v<=nbvtx;v++) {
368 if(newparamvertex(v)<0.) {
370 if((pv>=U-2.0*myTolOpenDomain) && (pv<=U+2.0*myTolOpenDomain)) {
371 if(pv-U > myTolParam) {
372 newparamvertex(v) = 1.000001;
374 else if(U-pv>myTolParam) {
375 newparamvertex(v) = 0.999999;
381 Standard_Real DeltaU;
385 //// Modified by jgv, 17.09.09 for OCC21255 ////
386 Standard_Boolean Corrected = Standard_False;
387 ////////////////////////////////////////////////
389 Standard_Integer NbCalculD1;
390 Standard_Real UPourCalculD1, pvavant, pvapres;
391 gp_Vec VPourCalculD1;
392 gp_Pnt PPourCalculD1;
398 if(aline->D1(UPourCalculD1,PPourCalculD1,VPourCalculD1)) {
399 Standard_Real NormV = VPourCalculD1.Magnitude();
400 if(NormV > 1.0e-16) {
406 else if (DeltaU > dumax)
408 UPourCalculD1+=dumin;
410 while((++NbCalculD1<10)&&(DeltaU==0.));
414 Standard_Real CurvDef = deflectionmax, AngDef = CurvDef;
415 if(U+DeltaU < lastparam) {
416 DefineDU(aline,U,DeltaU,CurvDef,AngDef);
421 DeltaU = (dumin+dumax)*0.5;
423 //--------------------------------------------------------
424 //-- On cherche a placer un minimum de ??? Points entre
426 //--------------------------------------------------------
427 pvavant = firstparam;
429 for(v=1;v<=nbvtx;v++) {
431 if(pv-U > myTolParam) {
437 if(U-pv > myTolParam) {
445 if(pvapres < (10.*DeltaU)) {
446 if(pvapres > (10.*dumin)) {
447 DeltaU = pvapres*0.1;
454 if (nbpwline==1 && nbvtx) {
455 Standard_Real aUnext;
460 DeltaU=0.5*(pv-firstparam);
464 //--------------------------------------------------------
465 //-- Calcul des nouveaux parametres sur les vertex
467 for(v=1;v<=nbvtx;v++) {
468 if(newparamvertex(v)<0.) {
470 if(pv>=U && pv<(U+DeltaU) && (U+DeltaU<lastparam) ) {
471 newparamvertex(v) = (Standard_Real)nbpwline + (pv-U)/DeltaU;
476 //// Modified by jgv, 17.09.09 for OCC21255 ////
477 if (!Corrected && U >= refpar)
479 CorrectFirstPartOfLine(LinOn2S, quad1, quad2, ref_u1, ref_u2, anu1, anu2);
480 Corrected = Standard_True;
482 ////////////////////////////////////////////////
486 Pnt3d = aline->Value(U);
487 quad1.Parameters(Pnt3d,u1,v1);
488 quad2.Parameters(Pnt3d,u2,v2);
489 RecadreMemePeriode(quad1, quad2, u1,u2,anu1,anu2);
492 POn2S.SetValue(Pnt3d,u1,v1,u2,v2);
495 }//while(U<lastparam)
498 for(v=1;v<=nbvtx;v++) {
499 if(newparamvertex(v)<0.) {
501 if(pv <= lastparam+myTolOpenDomain) {
503 newparamvertex(v) = (Standard_Real)nbpwline+(pv-U)/(lastparam-U);
506 newparamvertex(v) = nbpwline+1;
512 Pnt3d = aline->Value(lastparam);
513 quad1.Parameters(Pnt3d,u1,v1);
515 RefineParameters(aline, firstparam, lastparam, lastparam, -1, quad1, 10.*myTol3D, u1,v1);
517 quad2.Parameters(Pnt3d,u2,v2);
519 RefineParameters(aline, firstparam, lastparam, lastparam, -1, quad2, 10.*myTol3D, u2,v2);
521 RecadreMemePeriode(quad1, quad2, u1,u2,anu1,anu2);
522 POn2S.SetValue(Pnt3d,u1,v1,u2,v2);
526 //// Modified by jgv, 17.09.09 for OCC21255 ////
528 (lastparam >= refpar || refpar-lastparam < Precision::Confusion()))
529 CorrectFirstPartOfLine(LinOn2S, quad1, quad2, ref_u1, ref_u2, anu1, anu2);
530 ////////////////////////////////////////////////
533 //-----------------------------------------------------------------
534 //-- Calcul de la transition de la ligne sur les surfaces ---
535 //-----------------------------------------------------------------
536 IntSurf_TypeTrans trans1,trans2;
537 Standard_Integer indice1;
538 Standard_Real dotcross;
541 trans1=IntSurf_Undecided;
542 trans2=IntSurf_Undecided;
544 indice1 = nbpwline/3;
549 aPP1=LinOn2S->Value(indice1).Value();
550 aPP0=LinOn2S->Value(indice1-1).Value();
552 gp_Vec tgvalid(aPP0, aPP1);
553 gp_Vec aNQ1=quad1.Normale(aPP0);
554 gp_Vec aNQ2=quad2.Normale(aPP0);
556 dotcross = tgvalid.DotCross(aNQ2, aNQ1);
557 if (dotcross > myTolTransition) {
558 trans1 = IntSurf_Out;
561 else if(dotcross < -myTolTransition) {
563 trans2 = IntSurf_Out;
565 //-----------------------------------------------------------------
566 //-- C r e a t i o n d e la W L i n e ---
567 //-----------------------------------------------------------------
568 Handle(IntPatch_WLine) wline;
570 if(aline->TransitionOnS1() == IntSurf_Touch) {
571 Handle(IntPatch_WLine) wlinetemp = new IntPatch_WLine(LinOn2S,
573 aline->SituationS1(),
574 aline->SituationS2());
577 if(aline->TransitionOnS1() == IntSurf_Undecided) {
578 Handle(IntPatch_WLine) wlinetemp = new IntPatch_WLine(LinOn2S,
583 Handle(IntPatch_WLine) wlinetemp = new IntPatch_WLine(LinOn2S,
585 trans1, // aline->TransitionOnS1(),
586 trans2); //aline->TransitionOnS2());
590 //-----------------------------------------------------------------
591 //-- I n s e r t i o n d e s v e r t e x ---
592 //-----------------------------------------------------------------
593 TColStd_Array1OfInteger Redir(1,Max(nbvtx,1));
595 for(v=1;v<=nbvtx;v++) {
600 Standard_Integer tamp;
602 TriOk = Standard_True;
603 for(v=2; v<=nbvtx;v++) {
604 if(newparamvertex(Redir(v))<newparamvertex(Redir(v-1))) {
606 Redir(v-1) = Redir(v);
608 TriOk = Standard_False;
614 //-----------------------------------------------------------------
615 //-- On detecte le cas ou un Vtx de param 1 ou nbpwline OnArc est double
616 //-- Dans ce cas on supprime le vertex qui reference un arc deja reference
617 //-- par un autre vertex
618 //nbvtx = aline->NbVertex();
619 Standard_Boolean APointHasBeenRemoved;
622 Standard_Boolean RemoveVtxo, RemoveVtx;
623 Standard_Integer vo, voo;
624 Standard_Real ponl, ponlo, ponloo, aDist13, aDist23;
626 APointHasBeenRemoved = Standard_False;
627 RemoveVtxo = Standard_False;
628 RemoveVtx = Standard_False;
630 for(v=1; v<=nbvtx && !APointHasBeenRemoved; v++) {
632 if(newparamvertex(v)>=0.) {
633 const IntPatch_Point& Vtx = aline->Vertex(v);
634 ponl = Vtx.ParameterOnLine();
635 const gp_Pnt& aP=Vtx.Value();
637 for(vo=1; vo<=nbvtx && !APointHasBeenRemoved; vo++) {
639 if(newparamvertex(vo)>=0.) {
640 const IntPatch_Point& Vtxo = aline->Vertex(vo);
641 ponlo = Vtxo.ParameterOnLine();
642 const gp_Pnt& aPo=Vtxo.Value();
644 if(ponl-ponlo<myTolParam && ponlo-ponl<myTolParam) {
646 for(voo=1; voo<=nbvtx && !APointHasBeenRemoved; voo++) {
647 if(voo!=v && voo!=vo) {
648 if(newparamvertex(voo)>=0.) {
649 const IntPatch_Point& Vtxoo = aline->Vertex(voo);
650 ponloo = Vtxoo.ParameterOnLine();
651 const gp_Pnt& aPoo=Vtxoo.Value();
653 aDist13=aP.Distance(aPoo);
655 if(aDist13<=myTol3D) {
656 //-- 2 vertex de meme param + un confondu geometriquement
657 if((Vtx.IsOnDomS1() == Vtxoo.IsOnDomS1()) &&
658 (Vtx.IsOnDomS2() == Vtxoo.IsOnDomS2()) ) {
660 if(Vtx.IsOnDomS1()) {
661 if(Vtx.ParameterOnArc1()==Vtxoo.ParameterOnArc1()) {
662 if(SameCurve(Vtxoo.ArcOnS1(),Vtx.ArcOnS1())) { //-- param on s1 ?
663 RemoveVtx = Standard_True;
667 if(Vtx.IsOnDomS2()) {
668 if(Vtx.ParameterOnArc2()==Vtxoo.ParameterOnArc2()) {
669 if(SameCurve(Vtxoo.ArcOnS2(),Vtx.ArcOnS2())) {
670 RemoveVtx = Standard_True;
674 RemoveVtx = Standard_False;
679 if(RemoveVtx==Standard_False) {
681 aDist23=aPo.Distance(aPoo);
683 if(aDist23<=myTol3D) {
684 //-- 2 vertex de meme param + un confondu geometriquement
685 if((Vtxo.IsOnDomS1() == Vtxoo.IsOnDomS1())&&
686 (Vtxo.IsOnDomS2() == Vtxoo.IsOnDomS2()) ) {
687 if(Vtxo.IsOnDomS1()) {
688 if(Vtxo.ParameterOnArc1()==Vtxoo.ParameterOnArc1()) {
689 if(SameCurve(Vtxoo.ArcOnS1(),Vtxo.ArcOnS1())) { //-- param on s1 ?
690 RemoveVtxo = Standard_True;
694 if(Vtxo.IsOnDomS2()) {
695 if(Vtxo.ParameterOnArc2()==Vtxoo.ParameterOnArc2()) {
696 if(SameCurve(Vtxoo.ArcOnS2(),Vtxo.ArcOnS2())) {
697 RemoveVtxo = Standard_True;
701 RemoveVtxo = Standard_False;
708 newparamvertex(v) = -1.;
709 APointHasBeenRemoved = Standard_True;
711 else if(RemoveVtxo) {
712 newparamvertex(vo) = -1.;
713 APointHasBeenRemoved = Standard_True;
716 } //-- voo!=v && voo!=vo
717 } //-- Fin boucle sur voo
724 }//for(v=1; v<=nbvtx && !APointHasBeenRemoved; v++)
726 while(APointHasBeenRemoved);
728 Standard_Integer ParamVtxPrecedent, refpointonwline, aIndV;
729 Standard_Real pvtx, approxparamonwline, aDst;
730 Standard_Boolean bIsApex1, bIsApex2;
732 ParamVtxPrecedent = 0;
734 for(v=1; v<=nbvtx; v++) {
736 pv=paramvertex(v);// parameter from ALine
737 pvtx = newparamvertex(aIndV);
738 if(pvtx>=0. && (pvtx <= nbpwline+1)) {
739 approxparamonwline=newparamvertex(aIndV);
742 IntPatch_Point NewPoint = aline->Vertex(aIndV);
744 Pnt3d = NewPoint.Value();
745 quad1.Parameters(Pnt3d, u1, v1);
746 quad2.Parameters(Pnt3d, u2, v2);
747 //-------------------------------------------------------
748 //-- On recadre les parametres des vertex dans la bonne -
749 //-- periode en recadrant avec le point le plus proche -
750 //-------------------------------------------------------
751 if(approxparamonwline > nbpwline) {
752 refpointonwline = nbpwline-1;
754 else if(approxparamonwline < 1) {
758 refpointonwline = (Standard_Integer)approxparamonwline;
762 const IntSurf_PntOn2S& aP2Sx=LinOn2S->Value(refpointonwline);
763 aP2Sx.ParametersOnS1(anu1, anv1);
764 aP2Sx.ParametersOnS2(anu2, anv2);
766 bIsApex1=IsApex(quad1, v1, myTol3D);
767 bIsApex2=IsApex(quad2, v2, myTol3D);
769 //if (refpointonwline==1 || refpointonwline==nbpwline) {
770 if (bIsApex1 || bIsApex2) {
771 if (fabs(pv-firstparam)<myTolParam || fabs(pv-lastparam)<myTolParam) {
772 // aline starts(ends) on vertex
773 const gp_Pnt& aP1x=aP2Sx.Value();
775 aDst=aP1x.Distance(Pnt3d);
776 if (aDst<10.*myTol3D) {
785 // aline goes through vertex
797 ParamVtxPrecedent=refpointonwline;
798 RecadreMemePeriode(quad1, quad2, u1,u2,anu1,anu2);
799 NewPoint.SetParameter(refpointonwline);
801 NewPoint.SetParameters(u1,v1,u2,v2);
802 wline->AddVertex(NewPoint);
806 if(ParamVtxPrecedent==refpointonwline) {
807 //-- 2 vertex renseignent le meme point de la LineOn2S
808 //-- On insere un nv point = vtx
809 //-- On decale tous les vtx apres de 1
810 RecadreMemePeriode(quad1, quad2, u1,u2,anu1,anu2);
811 POn2S.SetValue(Pnt3d,u1,v1,u2,v2);
812 LinOn2S->InsertBefore(refpointonwline+1, POn2S);
814 NewPoint.SetParameter(refpointonwline+1);
815 NewPoint.SetParameters(u1,v1,u2,v2);
816 wline->AddVertex(NewPoint);
817 ParamVtxPrecedent = refpointonwline+1;
819 Standard_Integer vv=v+1;
820 for(; vv<=nbvtx; vv++) {
821 if(newparamvertex(Redir(vv))!=-1.) {
822 newparamvertex(Redir(vv))=newparamvertex(Redir(vv))+1.;
828 RecadreMemePeriode(quad1, quad2, u1,u2, anu1, anu2);
829 NewPoint.SetParameter(refpointonwline);
831 NewPoint.SetParameters(u1, v1, u2, v2);
832 wline->AddVertex(NewPoint);
833 ParamVtxPrecedent = refpointonwline;
844 switch(quad1.TypeQuadric()) {
845 case GeomAbs_Cylinder:
853 switch(quad2.TypeQuadric()) {
854 case GeomAbs_Cylinder:
862 wline->SetPeriod(pu1,pv1,pu2,pv2);
864 wline->ComputeVertexParameters(myTol3D);
867 //=======================================================================
868 //function : DefineDU
870 //=======================================================================
871 gp_Pnt DefineDU(const Handle(IntPatch_ALine)& aline,
872 const Standard_Real U,
874 const Standard_Real CurvDef,
875 const Standard_Real AngDef)
877 gp_Pnt P1 = aline->Value(U), P2, P3;
878 gp_Vec V13, V12, V23;
879 Standard_Real dU = DU/2.0, curvDef, angDef, m1, m2, m3;
880 do{ //According to class TangentialDeflection from GCPnts
881 P2=aline->Value(U+dU); P3=aline->Value(U+DU);
882 V13 = P3.XYZ().Subtracted(P1.XYZ()); m1 = V13.Magnitude();
883 V12 = P2.XYZ().Subtracted(P1.XYZ()); m2 = V12.Magnitude();
884 V23 = P3.XYZ().Subtracted(P2.XYZ()); m3 = V23.Magnitude();
885 if(m1 < CurvDef || m2 < CurvDef || m3 < CurvDef) break;
886 curvDef = Abs(V13.Angle(V12));
887 angDef = Abs(V13.Angle(V23));
888 if(curvDef < CurvDef && angDef < AngDef) break;
893 //=======================================================================
894 //function : SameCurve
896 //=======================================================================
897 Standard_Boolean SameCurve(const Handle_Adaptor2d_HCurve2d& C1,const Handle_Adaptor2d_HCurve2d& C2)
899 Standard_Real C1f = C1->FirstParameter();
900 Standard_Real C2f = C2->FirstParameter();
901 if(C1f!=C2f) return(Standard_False);
902 Standard_Real C1l = C1->LastParameter();
903 Standard_Real C2l = C2->LastParameter();
904 if(C1l!=C2l) return(Standard_False);
905 Standard_Real u=0.3*C1f+0.7*C1l;
906 gp_Pnt2d P1 = C1->Value(u);
907 gp_Pnt2d P2 = C2->Value(u);
908 if(P1.X()!=P2.X()) return(Standard_False);
909 if(P1.Y()!=P2.Y()) return(Standard_False);
910 return(Standard_True);
912 //=======================================================================
913 //function : RecadreMemePeriode
915 //=======================================================================
916 void RecadreMemePeriode(const IntSurf_Quadric aQuad1,
917 const IntSurf_Quadric aQuad2,
920 const Standard_Real anu1,
921 const Standard_Real anu2)
923 Standard_Boolean bBothCylinders;
924 GeomAbs_SurfaceType aType1, aType2;
926 aType1=aQuad1.TypeQuadric();
927 aType2=aQuad2.TypeQuadric();
928 bBothCylinders=(aType1==GeomAbs_Cylinder && aType2==GeomAbs_Cylinder);
930 while(anu1-u1 > 5.0) {
933 while(u1-anu1 > 5.0) {
936 if (!bBothCylinders) {//cfe900/H6
937 // this check on Cylinder/Cylinder intersection is probably
938 // because of pbs with ALine on it.
939 // For other Quadrics there was no pbs found during
941 // (it is necessary to see ...IntCyCy(...) for details).
943 // In any case the pb does not deal with apex problem.
953 while(anu2-u2 > 5.0) {
956 while(u2-anu2 > 5.0) {
959 if (!bBothCylinders) {//cfe900/H6
970 //=======================================================================
971 //function : CorrectFirstPartOfLine
973 //=======================================================================
974 void CorrectFirstPartOfLine(Handle(IntSurf_LineOn2S)& LinOn2S,
975 const IntSurf_Quadric aQuad1,
976 const IntSurf_Quadric aQuad2,
977 const Standard_Real ref_u1,
978 const Standard_Real ref_u2,
979 Standard_Real& new_u1,
980 Standard_Real& new_u2)
982 Standard_Integer nbp = LinOn2S->NbPoints();
983 Standard_Real u1, v1, u2, v2, OffsetOnS1, OffsetOnS2;
985 IntSurf_PntOn2S aPoint = LinOn2S->Value(nbp);
986 aPoint.Parameters(u1, v1, u2, v2);
990 RecadreMemePeriode(aQuad1, aQuad2, new_u1, new_u2, ref_u1, ref_u2);
991 OffsetOnS1 = new_u1 - u1;
992 OffsetOnS2 = new_u2 - u2;
993 if (Abs(OffsetOnS1) > 1. || Abs(OffsetOnS2) > 1.) //recadre on n*2*PI is done
996 for (i = 1; i <= nbp; i++)
998 aPoint = LinOn2S->Value(i);
999 aPoint.Parameters(u1, v1, u2, v2);
1000 LinOn2S->SetUV( i, Standard_True, u1 + OffsetOnS1, v1 );
1001 LinOn2S->SetUV( i, Standard_False, u2 + OffsetOnS2, v2 );
1007 //=======================================================================
1010 //=======================================================================
1011 Standard_Boolean IsApex(const IntSurf_Quadric& aQuadric,
1012 const Standard_Real aVx,
1013 const Standard_Real aTol3D)
1016 Standard_Boolean bFlag;
1017 Standard_Real aHalfPi, aEpsilon;
1018 GeomAbs_SurfaceType aType;
1020 bFlag=Standard_False;
1022 aType=aQuadric.TypeQuadric();
1023 if (!(aType==GeomAbs_Cone || aType==GeomAbs_Sphere)) {
1027 aEpsilon=Epsilon(10.);//1.77e-15
1029 // apex on the Sphere
1030 if(aType==GeomAbs_Sphere) {
1032 if (fabs(aVx-aHalfPi)<aEpsilon) {
1035 else if (fabs(aVx+aHalfPi)<aEpsilon){
1041 else if(aType==GeomAbs_Cone) {
1046 aCone=aQuadric.Cone();
1048 aPx=aQuadric.Value(0.,aVx);
1050 aDst=aPx.Distance(aPap);
1057 //=======================================================================
1058 //function : RefineParameters
1060 //=======================================================================
1061 void RefineParameters(const Handle(IntPatch_ALine)& aALine,
1062 const Standard_Real aTb,
1063 const Standard_Real aTe,
1064 const Standard_Real aTx,
1065 const Standard_Integer iDir,
1066 const IntSurf_Quadric& aQuadric,
1067 const Standard_Real aTol3D,
1071 GeomAbs_SurfaceType aType;
1073 aType=aQuadric.TypeQuadric();
1074 if (!(aType==GeomAbs_Cone || aType==GeomAbs_Sphere)) {
1078 Standard_Boolean bIsDone, bIsEmpty, bParallel, bFound;
1079 Standard_Integer aNbPoints;
1080 Standard_Real aHalfPi, aEpsilon, aLimV, dT, aT1, aT2, aEpsT;
1081 Standard_Real aU1, aV1, aU2, aV2;
1082 gp_Pnt aP1, aP2, aPx;
1083 gp_Pnt2d aP2D1, aP2D2, aPLim(0., 0.);
1084 gp_Vec2d aVLim(1., 0.);
1086 IntAna2d_AnaIntersection aAI;
1088 aEpsilon=Epsilon(10.);//1.77e-15
1090 aLLim.SetDirection(aVLim);
1093 if(aType==GeomAbs_Cone) {
1098 aCone=aQuadric.Cone();
1100 //aPx=aQuadric.Value(0.,aVx);
1101 aPx=aALine->Value(aTx);
1103 aDst=aPx.Distance(aPap);
1104 if(aDst>aTol3D) {// nothing to do
1109 aLLim.SetLocation(aPLim);
1113 // apex on the Sphere
1114 if(aType==GeomAbs_Sphere) {
1117 if (fabs(aVx-aHalfPi)<aEpsilon) {
1120 else if (fabs(aVx+aHalfPi)<aEpsilon){
1124 //Check: aUx must be 0 or 2*pi
1125 if(fabs(aUx) < aEpsilon || fabs(aUx - 2.*PI) < aEpsilon) {
1126 //aUx = 0 or 2*pi, but may be it must be 2*pi or 0?
1127 bFound=FindNearParameter(aALine, aTx, iDir, aTol3D, aT1);
1136 aP1=aALine->Value(aT1);
1137 aQuadric.Parameters(aP1, aU1, aV1);
1139 if(fabs(aU1) > fabs(aU1 - 2.*PI)) {
1151 aLLim.SetLocation(aPLim);
1156 // Try to find aT1, aT2 taking into acc 3D Tolerance
1157 bFound=FindNearParameter(aALine, aTx, iDir, aTol3D, aT1);
1159 bFound=FindNearParameter(aALine, aT1, iDir, aTol3D, aT2);
1162 // Assign aT1, aT2 by some values
1171 aP1=aALine->Value(aT1);
1172 aQuadric.Parameters(aP1, aU1, aV1);
1173 aP2D1.SetCoord(aU1, aV1);
1175 aP2=aALine->Value(aT2);
1176 aQuadric.Parameters(aP2, aU2, aV2);
1177 aP2D2.SetCoord(aU2, aV2);
1179 gp_Vec2d aV12(aP2D1, aP2D2);
1181 if(aV12.SquareMagnitude() <= aEpsilon) {
1184 gp_Lin2d aL12(aP2D1, aV12);
1186 aAI.Perform(aLLim, aL12);
1187 bIsDone=aAI.IsDone();
1191 bIsEmpty=aAI.IsEmpty();
1195 aNbPoints=aAI.NbPoints();
1199 bParallel=aAI.ParallelElements();
1203 const IntAna2d_IntPoint& aIAPnt=aAI.Point(1);
1204 const gp_Pnt2d& aP2D=aIAPnt.Value();
1207 //=======================================================================
1208 //function : FindNearParameter
1210 //=======================================================================
1211 Standard_Boolean FindNearParameter(const Handle(IntPatch_ALine)& aALine,
1212 const Standard_Real aTx,
1213 const Standard_Integer iDir,
1214 const Standard_Real aTol3D,
1217 Standard_Boolean bFound;
1218 Standard_Real aX, aY, aZ;
1224 bFound=aALine->D1(aTx, aPx, aVx);
1232 aX=aPx.X()+aDx.X()*aTol3D;
1233 aY=aPx.Y()+aDx.Y()*aTol3D;
1234 aZ=aPx.Z()+aDx.Z()*aTol3D;
1235 aP1.SetCoord(aX, aY, aZ);
1237 bFound=aALine->FindParameter(aP1, aT1);