88a5a48e73ab5e8658dac83d0b2276859d3dc2aa
[occt.git] / src / ChFiKPart / ChFiKPart_ComputeData_ChAsymPlnCyl.cxx
1 // File:        ChFiKPart_ComputeData_ChAsymPlnCyl.cxx
2 // Created:     Tue Jun 16 11:22:58 1998
3 // Author:      Philippe NOUAILLE
4 //              <pne@cleox.paris1.matra-dtv.fr>
5
6
7 #include <ChFiKPart_ComputeData.ixx>
8
9 #include <Precision.hxx>
10 #include <gp.hxx>
11 #include <gp_Ax22d.hxx>
12 #include <gp_Pnt2d.hxx>
13 #include <gp_Dir2d.hxx>
14 #include <gp_Circ2d.hxx>
15 #include <gp_Pnt.hxx>
16 #include <gp_Dir.hxx>
17 #include <gp_Vec.hxx>
18 #include <gp_Circ.hxx>
19 #include <gp_Ax2.hxx>
20 #include <gp_Ax3.hxx>
21 #include <gp_Lin2d.hxx>
22
23 #include <ElCLib.hxx>
24 #include <ElSLib.hxx>
25
26 #include <Geom_ConicalSurface.hxx>
27 #include <Geom2d_Line.hxx>
28 #include <Geom_Line.hxx>
29 #include <Geom2d_Circle.hxx>
30 #include <Geom_Circle.hxx>
31 #include <Geom_Plane.hxx>
32 #include <IntAna_QuadQuadGeo.hxx>
33
34 #include <ChFiKPart_ComputeData_Fcts.hxx>
35
36
37 //pour tester
38
39 #include <Geom_CylindricalSurface.hxx>
40
41
42 //=======================================================================
43 //function : MakeChAsym
44 //purpose  : Compute the chamfer in the particular case Plane/Cylinder
45 //           or Cylinder/Plane
46 //           Compute the SurfData <Data> of the chamfer build on the <Spine>
47 //           between the plane <Pln> and the cylinder <Cyl>, with the 
48 //           distances <Dis> and <Angle> on <Pln> on <Cyl>.
49 //           <Or1> and <Or2> are the orientations of <Pln> and <Cyl>
50 //           and <Ofpl> this of the face carried by <Pln>.
51 //           <First> is the start point on the <Spine>
52 //           <Plandab> is equal to True if the plane is the surface S1
53 //           <fu> and <lu> are the first and last u parameters of the
54 //           cylinder
55 //           DisOnPlan is equal to True if Dis on plan, else False 
56 //out      : True if the chanfer has been computed
57 //           False else
58 //=======================================================================
59
60 Standard_Boolean ChFiKPart_MakeChAsym(TopOpeBRepDS_DataStructure& DStr,
61                                       const Handle(ChFiDS_SurfData)& Data, 
62                                       const gp_Pln& Pln, 
63                                       const gp_Cylinder& Cyl, 
64                                       const Standard_Real fu,
65                                       const Standard_Real lu,
66                                       const TopAbs_Orientation Or1,
67                                       const TopAbs_Orientation Or2,
68                                       const Standard_Real Dis, 
69                                       const Standard_Real Angle,
70                                       const gp_Circ& Spine, 
71                                       const Standard_Real First, 
72                                       const TopAbs_Orientation Ofpl,
73                                       const Standard_Boolean plandab,
74                                       const Standard_Boolean DisOnP)
75 {
76   // compute the chamfer surface(cone)
77
78   // compute the normals to the plane surface & to the plane face
79   gp_Ax3 PosPl = Pln.Position();
80   gp_Dir Dpl   = PosPl.XDirection().Crossed(PosPl.YDirection());
81   gp_Dir norf  = Dpl;
82   if ( Ofpl == TopAbs_REVERSED) norf.Reverse();
83   if (Or1 == TopAbs_REVERSED) Dpl.Reverse();
84
85   // compute the origin Or of the cone
86   gp_Pnt Or = Cyl.Location();
87   Standard_Real u, v;
88   ElSLib::PlaneParameters(PosPl, Or, u, v);
89   gp_Pnt2d pt2dPln(u, v);
90   ElSLib::PlaneD0(u, v, PosPl, Or);
91   gp_Pnt PtPl = Or;  // projection of the cylinder origin 
92                      //on the plane 
93
94   gp_Pnt PtSp;//start 3d point on the Spine 
95   gp_Vec DSp; //tangent vector to the spine on PtSp
96   ElCLib::D1(First, Spine, PtSp, DSp);
97   gp_Dir Dx(gp_Vec(Or, PtSp));
98   gp_Dir Dy(DSp);
99   ElSLib::Parameters(Cyl, PtSp, u, v);
100   gp_Pnt PtCyl;//point on the cylinder and on the Spine
101   gp_Vec Vu, Vv;
102   ElSLib::D1(u, v, Cyl, PtCyl, Vu, Vv);
103   gp_Dir Dcyl(Vu.Crossed(Vv));//normal to the cylinder in PtSp
104   if (Or2 == TopAbs_REVERSED) Dcyl.Reverse();
105   Standard_Boolean dedans = ( Dcyl.Dot(Dx) <= 0.);
106
107   Standard_Boolean pointu = Standard_False;
108   Standard_Real ConRad, Rad, SemiAngl;
109
110   //Calculation of distance
111   Standard_Real dis1, dis2, cosNPCyl, sinNPCyl;
112
113   if ( (plandab && DisOnP) || (!plandab && !DisOnP) ) {
114     dis1     = Dis;
115     cosNPCyl = Dpl.Dot(Dcyl);
116     sinNPCyl = sqrt(1. - cosNPCyl * cosNPCyl);
117     dis2     = Dis / (sinNPCyl / tan(Angle) - cosNPCyl);
118   } 
119   else {
120     dis2     = Dis;
121     cosNPCyl = Dpl.Dot(Dcyl);
122     sinNPCyl = sqrt(1. - cosNPCyl * cosNPCyl);
123     dis1     = Dis / (sinNPCyl / tan(Angle) - cosNPCyl);    
124   }
125
126   Or.SetCoord(Or.X() + dis2 * Dpl.X(),
127               Or.Y() + dis2 * Dpl.Y(),
128               Or.Z() + dis2 * Dpl.Z());
129
130       // variables used to compute the semiangle of the cone
131   gp_Dir Vec1(Or.X() - PtPl.X(), Or.Y() - PtPl.Y(), Or.Z() - PtPl.Z()); 
132   gp_Pnt Pt(Or.X() + dis1*PosPl.XDirection().X(),
133             Or.Y() + dis1*PosPl.XDirection().Y(),
134             Or.Z() + dis1*PosPl.XDirection().Z());
135   gp_Dir Vec2( Pt.X() - PtPl.X(), Pt.Y() - PtPl.Y(), Pt.Z() - PtPl.Z());
136
137   // compute the parameters of the conical surface
138   if (dedans) {
139     Rad = Cyl.Radius() - dis1;
140     if ( Abs(Rad) <= Precision::Confusion() ) pointu = Standard_True;
141     if(Rad < 0 ) {
142       cout<<"the chamfer can't pass"<<endl;
143       return Standard_False;
144     }
145   }
146   else {
147     Rad = Cyl.Radius() + dis1;
148     gp_Dir Dplr = Dpl.Reversed();
149     Dpl = Dplr;
150    }
151   ConRad   = Cyl.Radius();
152   SemiAngl = Vec1.Angle(Vec2);
153   gp_Ax3 ConAx3(Or, Dpl, Dx);
154
155   Handle (Geom_ConicalSurface)
156     gcon = new Geom_ConicalSurface( ConAx3, SemiAngl, ConRad );
157
158   // changes due to the fact the parameters of the chamfer must go increasing
159   // from surface S1 to surface S2
160   if ( (dedans && !plandab) || (!dedans && plandab) ) {
161     gcon->VReverse();// be carefull : the SemiAngle was changed
162     ConAx3   = gcon->Position();
163     SemiAngl = gcon->SemiAngle();
164   }
165
166       // changes due to the fact we have reversed the V direction of 
167       // parametrization
168   if (ConAx3.YDirection().Dot(DSp) <= 0.) {
169     ConAx3.YReverse();
170     gcon->SetPosition(ConAx3);
171   }
172
173   Data->ChangeSurf(ChFiKPart_IndexSurfaceInDS(gcon, DStr));
174
175   // compute the chamfer's orientation according to the orientation
176   // of the faces
177
178   //search the normal to the cone
179   gp_Vec deru, derv;
180   ElSLib::ConeD1(0., 0., ConAx3, ConRad, SemiAngl, Pt, deru, derv);
181
182   gp_Dir norCon(deru.Crossed(derv));
183   
184   Standard_Boolean toreverse = ( norCon.Dot(norf) <= 0.);
185   if (toreverse) {
186     Data->ChangeOrientation() = TopAbs_REVERSED; 
187   }
188   else {
189     Data->ChangeOrientation() = TopAbs_FORWARD; 
190   }
191   
192   //we load of the faceInterference with the pcurves and
193   // the 3d curves
194
195   // Case of the plane face
196   // NB: in the case 'pointu', no pcurve on the plane surface
197   // and no intersection plane-chamfer are needed
198   Handle(Geom2d_Circle) GCir2dPln;
199   Handle(Geom_Circle) GCirPln;
200   gp_Ax2 CirAx2 = ConAx3.Ax2();
201   CirAx2.SetLocation(PtPl);
202
203   if (!pointu) {
204       // intersection plane-chamfer
205     gp_Circ CirPln(CirAx2, Rad);
206     GCirPln = new Geom_Circle(CirPln);
207
208     //pcurve on the plane
209     ElSLib::PlaneParameters(PosPl, Pt, u, v);
210     gp_Pnt2d p2dPln(u, v);
211     gp_Dir2d d2d(DSp.Dot(PosPl.XDirection()), DSp.Dot(PosPl.YDirection()));
212     gp_Ax22d ax2dPln(pt2dPln, gp_Dir2d(gp_Vec2d(pt2dPln, p2dPln)), d2d);
213     gp_Circ2d cir2dPln(ax2dPln, Rad);
214     GCir2dPln = new Geom2d_Circle(cir2dPln);
215   }
216
217   //pcurve on the chamfer
218   gp_Pnt2d p2dch;
219   if (plandab) 
220     v= -sqrt(dis1 * dis1 + dis2 * dis2);
221   else 
222     v = sqrt(dis1 * dis1 + dis2 * dis2);
223   p2dch.SetCoord(0., v);
224   ElSLib::ConeD1(0., v, ConAx3, ConRad, SemiAngl, Pt, deru, derv);
225   gp_Lin2d lin2dch(p2dch, gp::DX2d());
226   Handle(Geom2d_Line) GLin2dCh1 = new Geom2d_Line(lin2dch);
227
228   //orientation
229   TopAbs_Orientation trans; 
230   gp_Dir norpl = PosPl.XDirection().Crossed(PosPl.YDirection());
231   toreverse = ( norCon.Dot(norpl) <= 0. );
232   if ((toreverse && plandab) || (!toreverse && !plandab)){ 
233     trans = TopAbs_FORWARD;
234   }
235   else { 
236     trans = TopAbs_REVERSED; 
237   }
238
239
240   if(plandab){
241     Data->ChangeInterferenceOnS1().
242       SetInterference(ChFiKPart_IndexCurveInDS(GCirPln, DStr),
243                       trans, GCir2dPln, GLin2dCh1);
244   }
245   else{
246     Data->ChangeInterferenceOnS2().
247       SetInterference(ChFiKPart_IndexCurveInDS(GCirPln, DStr),
248                       trans,GCir2dPln, GLin2dCh1);
249   }
250
251   // Case of the cylindrical face
252
253   //intersection cylinder-chamfer
254   CirAx2.SetLocation(Or);
255   gp_Circ CirCyl(CirAx2, ConRad);
256   Handle(Geom_Circle) GCirCyl = new Geom_Circle(CirCyl);
257
258   //pcurve on the chamfer
259   p2dch.SetCoord(0., 0.);
260   ElSLib::ConeD1(0., 0., ConAx3, ConRad, SemiAngl, Pt, deru, derv);
261   lin2dch.SetLocation(p2dch);
262   Handle(Geom2d_Line) GLin2dCh2 = new Geom2d_Line(lin2dch);
263
264   //pcurve on the cylinder
265   norCon.SetXYZ (deru.Crossed(derv).XYZ());
266
267   Pt.SetCoord(Or.X() + ConRad * Dx.X(),
268               Or.Y() + ConRad * Dx.Y(),
269               Or.Z() + ConRad * Dx.Z());
270   ElSLib::Parameters(Cyl, Pt ,u, v);
271   Standard_Real tol = Precision::PConfusion();
272   Standard_Boolean careaboutsens = 0;
273   if(Abs(lu - fu - 2 * PI) < tol) careaboutsens = 1;
274   if(u >= fu - tol && u < fu) u = fu;
275   if(u <= lu + tol && u > lu) u = lu;
276   if(u < fu || u > lu) u = ChFiKPart_InPeriod(u, fu, fu + 2 * PI, tol);
277
278   ElSLib::D1(u, v, Cyl, Pt, deru, derv);
279   gp_Dir   norcyl = deru.Crossed(derv);
280   gp_Dir2d d2dCyl = gp::DX2d();
281   if( deru.Dot(Dy) < 0. ){
282     d2dCyl.Reverse(); 
283     if(careaboutsens && Abs(fu - u)<tol) u = lu;
284   }
285   else if(careaboutsens && Abs(lu - u)<tol) u = fu;
286   gp_Pnt2d p2dCyl(u, v);
287   gp_Lin2d lin2dCyl(p2dCyl, d2dCyl);
288   Handle(Geom2d_Line) GLin2dCyl = new Geom2d_Line(lin2dCyl);
289
290       //orientation
291   toreverse = ( norCon.Dot(norcyl) <= 0. );
292   if ((toreverse && plandab) || (!toreverse && !plandab) ) {
293     trans = TopAbs_REVERSED;
294   }
295   else {
296     trans = TopAbs_FORWARD;
297   }
298
299   if(plandab){
300     Data->ChangeInterferenceOnS2().
301       SetInterference(ChFiKPart_IndexCurveInDS(GCirCyl, DStr),
302                       trans, GLin2dCyl, GLin2dCh2);
303   }
304   else{
305     Data->ChangeInterferenceOnS1().
306       SetInterference(ChFiKPart_IndexCurveInDS(GCirCyl, DStr),
307                       trans, GLin2dCyl, GLin2dCh2);
308   }
309
310   return Standard_True;
311 }
312
313
314 //=======================================================================
315 //function : MakeChAsym
316 //purpose  : case cylinder/plane or plane/cylinder.
317 //=======================================================================
318
319 Standard_Boolean ChFiKPart_MakeChAsym(TopOpeBRepDS_DataStructure& DStr,
320                                       const Handle(ChFiDS_SurfData)& Data, 
321                                       const gp_Pln& Pln, 
322                                       const gp_Cylinder& Cyl, 
323                                       const Standard_Real fu,
324                                       const Standard_Real lu,
325                                       const TopAbs_Orientation Or1,
326                                       const TopAbs_Orientation Or2,
327                                       const Standard_Real Dis, 
328                                       const Standard_Real Angle,
329                                       const gp_Lin& Spine, 
330                                       const Standard_Real First, 
331                                       const TopAbs_Orientation Ofpl,
332                                       const Standard_Boolean plandab,
333                                       const Standard_Boolean DisOnP)
334 {
335   // calculation of the fillet plane.
336   // or1 and or2 permit to determine in which of four sides created by
337   // intersection of 2 surfaces we are
338   //        _|_          Ofpl is orientation of the plane face allowing
339   //         |4          to determine the side of the material
340
341   gp_Pnt OrSpine = ElCLib::Value(First, Spine);
342   gp_Pnt POnCyl, POnPln, OrCyl;
343
344   gp_Dir XDir = Spine.Direction();
345   gp_Ax3 AxPln  = Pln.Position();
346   gp_Dir NorPln = AxPln.XDirection().Crossed(AxPln.YDirection());
347   gp_Dir NorF(NorPln);
348   if (Or1 == TopAbs_REVERSED)
349     {NorF.Reverse();} 
350
351   gp_Ax3 AxCyl = Cyl.Position();
352   // OrCyl is the point on axis of cylinder in the plane normal to the
353   // axis containing OrSpine
354   gp_Pnt Loc = AxCyl.Location();
355   gp_Vec LocSp(Loc, OrSpine);
356   gp_XYZ temp = AxCyl.Direction().XYZ();
357   temp = temp.Multiplied(LocSp.XYZ().Multiplied(temp) );
358   OrCyl.SetXYZ( (Loc.XYZ()).Added(temp) );
359  
360   //construction of POnPln
361   gp_Vec VecTranslPln,tmp;
362
363  tmp = gp_Vec(OrSpine,OrCyl);
364   if ((Or2 == TopAbs_FORWARD && Cyl.Direct()) ||
365       (Or2 == TopAbs_REVERSED && !Cyl.Direct()))
366     {tmp.Reverse();}
367
368   VecTranslPln = gp_Vec( XDir.Crossed(NorPln) );
369   if( VecTranslPln.Dot(tmp) <= 0. )
370      {VecTranslPln.Reverse();}
371
372   gp_Vec VecTranslCyl;
373   VecTranslCyl = gp_Vec(OrSpine,OrCyl);
374
375   // Calculation of distances dis1 and dis2, depending on Dis and Angle
376   gp_Vec DirSOrC = VecTranslCyl.Normalized();
377   Standard_Real cosA1 = DirSOrC.Dot(VecTranslPln.Normalized());
378   Standard_Real sinA1 = Sqrt(1. - cosA1 * cosA1);
379 #ifndef DEB
380   Standard_Real dis1 = 0.;
381 #else
382   Standard_Real dis1;
383 #endif
384   Standard_Real dis2, ray = Cyl.Radius(); 
385   Standard_Boolean IsDisOnP = ( (plandab && DisOnP) || (!plandab && !DisOnP) ); 
386  
387   if (IsDisOnP) {
388     dis1 = Dis;
389     Standard_Real sinAl = Sin(Angle), cosAl = Cos(Angle);
390     Standard_Real h = dis1 * sinAl; 
391     Standard_Real cosAhOC = cosA1 * sinAl + sinA1 * cosAl;
392     Standard_Real sinAhOC = sinA1 * sinAl - cosA1 * cosAl;
393     if (cosA1 > 0) sinAhOC = -sinAhOC;
394     Standard_Real temp1 = h / ray,
395                   temp2 = sinAhOC * sinAhOC + temp1 * cosAhOC;
396
397     dis2 = temp2 + temp1 * (cosAhOC - temp1);
398
399     if (dis2 < -1.E-09) {
400       cout<<"too great angle of chamfer"<<endl;
401       return Standard_False;
402     }
403     else if (dis2 < 1.E-09) {
404       dis2 = ray * Sqrt(2. * temp2);
405     }
406     else {
407       dis2 = ray * Sqrt(2. * (temp2 - sinAhOC * Sqrt(dis2)) );
408     }
409   }
410   else {
411     dis2 = Dis;
412   }
413
414   //construction of POnCyl 
415   Standard_Real alpha = ( 2*ASin(dis2*0.5/ray) );
416   gp_Vec VecTemp = VecTranslCyl.Reversed();
417
418   if ( ( XDir.Crossed(gp_Dir(VecTranslCyl)) ).Dot(NorF) < 0.) {
419     VecTemp.Rotate(gp_Ax1(OrCyl,XDir),alpha);
420   }
421   else { 
422     VecTemp.Rotate(gp_Ax1(OrCyl,XDir.Reversed()),alpha);}
423
424   POnCyl.SetXYZ( OrCyl.XYZ().Added(VecTemp.XYZ()) );
425   Standard_Real UOnCyl,VOnCyl,UOnPln,VOnPln;
426   gp_Vec DUOnCyl, DVOnCyl;
427   ElSLib::Parameters(Cyl,POnCyl,UOnCyl,VOnCyl);
428   ElSLib::CylinderD1(UOnCyl, VOnCyl, AxCyl, Cyl.Radius(),
429                      POnCyl, DUOnCyl, DVOnCyl);         
430
431   // Construction of the point on the plane
432   if (!IsDisOnP) {
433     gp_Vec Corde(POnCyl, OrSpine);
434     gp_Vec TCyl = DUOnCyl.Crossed(DVOnCyl);
435
436     TCyl =  XDir.Crossed(TCyl);
437     TCyl.Normalize();
438     Corde.Normalize();
439     Standard_Real cosCorTan = TCyl.Dot(Corde);
440     Standard_Real tgCorTan = 1. / (cosCorTan * cosCorTan);
441     tgCorTan = Sqrt(tgCorTan - 1.);
442
443     Standard_Real tgAng  = tan(Angle);
444     tgAng = (tgAng + tgCorTan) / (1. - tgAng * tgCorTan);
445
446     Standard_Real cosA11 = dis2 / (2. * ray);
447     Standard_Real sinA11 = Sqrt(1. - cosA11 * cosA11);
448     if (cosA1 > 0) sinA11 = -sinA11;
449     dis1  = (sinA1 + cosA1 * tgAng) * cosA11;
450     dis1 -= (cosA1 - sinA1 * tgAng) * sinA11;
451     dis1  = (dis2 * tgAng) / dis1;
452   }  
453
454   VecTranslPln.Multiply(dis1);
455
456   POnPln.SetXYZ( (OrSpine.XYZ()).Added(VecTranslPln.XYZ()) );
457
458   //construction of the chamfer  
459   ElSLib::Parameters(Pln,POnPln,UOnPln,VOnPln);
460   POnPln = ElSLib::PlaneValue(UOnPln,VOnPln,AxPln);
461
462   //construction of YDir to go from face1 to face2.
463   gp_Vec YDir(POnPln,POnCyl);
464   if (!plandab){ 
465     YDir.Reverse();
466   }
467   gp_Ax3 AxCh(POnPln,XDir.Crossed(YDir),XDir);
468
469   Handle(Geom_Plane) Chamfer = new Geom_Plane(AxCh);
470   Data->ChangeSurf(ChFiKPart_IndexSurfaceInDS(Chamfer,DStr));
471
472   // FaceInterferences are loaded with pcurves and curves 3d.
473      //----------- edge plan-Chamfer
474   gp_Pnt2d PPln2d(UOnPln,VOnPln);
475   gp_Dir2d VPln2d(XDir.Dot(AxPln.XDirection()),
476                   XDir.Dot(AxPln.YDirection()));
477   gp_Lin2d Lin2dPln(PPln2d,VPln2d);
478
479   POnPln = ElSLib::Value(UOnPln,VOnPln,Pln);
480   gp_Lin   C3d(POnPln,XDir);
481
482   Standard_Real U,VOnChamfer;
483   ElSLib::PlaneParameters(AxCh,POnPln,U,VOnChamfer);
484   gp_Lin2d LOnChamfer(gp_Pnt2d(U,VOnChamfer),gp::DX2d());
485
486   Handle(Geom_Line)   L3d  = new Geom_Line  (C3d);
487   Handle(Geom2d_Line) LFac = new Geom2d_Line(Lin2dPln);
488   Handle(Geom2d_Line) LFil = new Geom2d_Line(LOnChamfer);
489
490   gp_Dir NorFil=AxCh.Direction();
491   Standard_Boolean toreverse = ( NorFil.Dot(NorPln) <= 0. );
492   gp_Dir DirPlnCyl(gp_Vec(POnPln, POnCyl));
493   gp_Dir DirSPln(gp_Vec(OrSpine, POnPln));
494   Standard_Boolean PosChamfPln = DirPlnCyl.Dot(DirSPln) > 0;
495
496   if ( !IsDisOnP && PosChamfPln )
497     toreverse = !toreverse;
498   // It is checked if the orientation of the Chamfer is the same as of the plane
499   if (toreverse)
500     {Data->ChangeOrientation() = TopAbs::Reverse(Ofpl);}
501   else          
502     {Data->ChangeOrientation() = Ofpl;}
503
504   TopAbs_Orientation trans = TopAbs_FORWARD;
505   if ((!plandab && toreverse) || (plandab && !toreverse))
506     {trans=TopAbs_REVERSED;}
507   
508   //trans allows to determine the "material" side on S1(2) limited by L3d
509   if (plandab) 
510     {Data->ChangeInterferenceOnS1().
511      SetInterference(ChFiKPart_IndexCurveInDS(L3d,DStr),trans,LFac,LFil);}
512   else    
513     {Data->ChangeInterferenceOnS2().
514      SetInterference(ChFiKPart_IndexCurveInDS(L3d,DStr),trans,LFac,LFil);}
515   
516      //------------edge cylindre-Chamfer        
517   gp_Pnt2d PCyl2d(UOnCyl,VOnCyl);
518   gp_Dir2d VCyl2d=gp::DY2d();
519   if ( XDir.Dot(AxCyl.Direction())<0 )
520     {VCyl2d.Reverse();}
521   gp_Lin2d Lin2dCyl(PCyl2d,VCyl2d);
522
523   POnCyl = ElSLib::Value(UOnCyl,VOnCyl,Cyl);
524   C3d = gp_Lin(POnCyl,XDir);
525
526   ElSLib::PlaneParameters(AxCh,POnCyl,U,VOnChamfer);
527   LOnChamfer = gp_Lin2d(gp_Pnt2d(U,VOnChamfer),gp::DX2d());
528
529   L3d  = new Geom_Line  (C3d);
530   LFac = new Geom2d_Line(Lin2dCyl);
531   LFil = new Geom2d_Line(LOnChamfer);
532
533   gp_Vec deru,derv;            
534   ElSLib::CylinderD1(UOnCyl,VOnCyl,AxCyl,Cyl.Radius(),POnCyl,deru,derv);
535   gp_Dir NorCyl(deru.Crossed(derv));    
536   gp_Dir DirSCyl(gp_Vec(OrSpine, POnCyl));
537   Standard_Boolean PosChamfCyl = DirPlnCyl.Dot(DirSCyl) < 0;
538   toreverse = ( NorFil.Dot(NorCyl) <= 0. );
539
540
541   if ( IsDisOnP && PosChamfCyl) 
542      toreverse = !toreverse; 
543   trans = TopAbs_REVERSED;
544   if ((!plandab && toreverse) || (plandab && !toreverse))
545     {trans=TopAbs_FORWARD;}
546
547   if (plandab) 
548     Data->ChangeInterferenceOnS2().
549     SetInterference(ChFiKPart_IndexCurveInDS(L3d,DStr),trans,LFac,LFil);
550   else    
551     Data->ChangeInterferenceOnS1().
552     SetInterference(ChFiKPart_IndexCurveInDS(L3d,DStr),trans,LFac,LFil);
553   return Standard_True;
554 }       
555
556
557
558
559
560
561