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