0027960: Configuration - fix compilation of OSD_Directory with MinGW-w64
[occt.git] / src / ChFiKPart / ChFiKPart_ComputeData_ChPlnCyl.cxx
1 // Created on: 1995-05-19
2 // Created by: Flore Lantheaume
3 // Copyright (c) 1995-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 : MakeChamfer
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 <Dis1> on <Pln> and <Dis2> 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 //out      : True if the chanfer has been computed
63 //           False else
64 //=======================================================================
65 Standard_Boolean ChFiKPart_MakeChamfer(TopOpeBRepDS_DataStructure& DStr,
66                                        const Handle(ChFiDS_SurfData)& Data, 
67                                        const gp_Pln& Pln, 
68                                        const gp_Cylinder& Cyl, 
69                                        const Standard_Real fu,
70                                        const Standard_Real lu,
71                                        const TopAbs_Orientation Or1,
72                                        const TopAbs_Orientation Or2,
73                                        const Standard_Real Dis1, 
74                                        const Standard_Real Dis2,
75                                        const gp_Circ& Spine, 
76                                        const Standard_Real First, 
77                                        const TopAbs_Orientation Ofpl,
78                                        const Standard_Boolean plandab)
79 {
80
81   // compute the chamfer surface(cone)
82
83     // compute the normals to the plane surface & to the plane face
84   gp_Ax3 PosPl = Pln.Position();
85   gp_Dir Dpl = PosPl.XDirection().Crossed(PosPl.YDirection());
86   gp_Dir norf = Dpl;
87   if ( Ofpl == TopAbs_REVERSED) norf.Reverse();
88   if (Or1 == TopAbs_REVERSED) Dpl.Reverse();
89
90     // compute the origin Or of the cone
91   gp_Pnt Or = Cyl.Location();
92   Standard_Real u,v;
93   ElSLib::PlaneParameters(PosPl,Or,u,v);
94   gp_Pnt2d pt2dPln(u,v);
95   ElSLib::PlaneD0(u,v,PosPl,Or);
96   gp_Pnt PtPl = Or;  // projection of the cylinder origin 
97                      //on the plane 
98
99   gp_Pnt PtSp;//start 3d point on the Spine 
100   gp_Vec DSp; //tangent vector to the spine on PtSp
101   ElCLib::D1(First,Spine,PtSp,DSp);
102   gp_Dir Dx(gp_Vec(Or,PtSp));
103   gp_Dir Dy(DSp);
104   ElSLib::Parameters(Cyl,PtSp,u,v);
105   gp_Pnt PtCyl;//point on the cylinder and on the Spine
106   gp_Vec Vu,Vv;
107   ElSLib::D1(u,v,Cyl,PtCyl,Vu,Vv);
108   gp_Dir Dcyl(Vu.Crossed(Vv));//normal to the cylinder in PtSp
109   if (Or2 == TopAbs_REVERSED) Dcyl.Reverse();
110   Standard_Boolean dedans = ( Dcyl.Dot(Dx) <= 0.);
111
112   Standard_Boolean pointu = Standard_False;
113   Standard_Real ConRad, Rad, SemiAngl ;
114   Or.SetCoord(Or.X()+Dis2*Dpl.X(),
115               Or.Y()+Dis2*Dpl.Y(),
116               Or.Z()+Dis2*Dpl.Z());
117
118       // variables used to compute the semiangle of the cone
119   gp_Dir Vec1(Or.X()-PtPl.X(), Or.Y()-PtPl.Y(), Or.Z()-PtPl.Z()); 
120   gp_Pnt Pt(Or.X()+Dis1*PosPl.XDirection().X(),
121             Or.Y()+Dis1*PosPl.XDirection().Y(),
122             Or.Z()+Dis1*PosPl.XDirection().Z());
123   gp_Dir Vec2( Pt.X()-PtPl.X(), Pt.Y()-PtPl.Y(), Pt.Z()-PtPl.Z());
124
125       // compute the parameters of the conical surface
126   if (dedans) {
127     Rad = Cyl.Radius()- Dis1;
128     if ( Abs(Rad) <= Precision::Confusion() ) pointu = Standard_True;
129     if(Rad < 0 ) {
130 #ifdef OCCT_DEBUG
131       cout<<"the chamfer can't pass"<<endl;
132 #endif
133       return Standard_False;
134     }
135   }
136   else {
137     Rad = Cyl.Radius()+Dis1;
138     gp_Dir Dplr = Dpl.Reversed();
139     Dpl = Dplr;
140    }
141   ConRad = Cyl.Radius();
142   SemiAngl = Vec1.Angle(Vec2);
143   gp_Ax3 ConAx3(Or,Dpl,Dx);
144
145   Handle (Geom_ConicalSurface)
146     gcon = new Geom_ConicalSurface( ConAx3, SemiAngl, ConRad );
147
148     // changes due to the fact the parameters of the chamfer must go increasing
149     // from surface S1 to surface S2
150   if ( (dedans && !plandab) || (!dedans && plandab) ) {
151     gcon->VReverse();// be carefull : the SemiAngle was changed
152     ConAx3 = gcon->Position();
153     SemiAngl = gcon->SemiAngle();
154   }
155
156       // changes due to the fact we have reversed the V direction of 
157       // parametrization
158   if (ConAx3.YDirection().Dot(DSp) <= 0.) {
159     ConAx3.YReverse();
160     gcon->SetPosition(ConAx3);
161   }
162
163   Data->ChangeSurf(ChFiKPart_IndexSurfaceInDS(gcon,DStr));
164
165
166   // compute the chamfer's orientation according to the orientation
167   // of the faces
168
169     //search the normal to the cone
170
171   gp_Vec deru, derv;
172   ElSLib::ConeD1(0.,0.,ConAx3,ConRad,SemiAngl,Pt,deru,derv);
173
174   gp_Dir norCon(deru.Crossed(derv));
175   
176   Standard_Boolean toreverse = ( norCon.Dot(norf) <= 0.);
177   if (toreverse) {
178     Data->ChangeOrientation() = TopAbs_REVERSED; 
179   }
180   else {
181     Data->ChangeOrientation() = TopAbs_FORWARD; 
182   }
183   
184   //we load of the faceInterference with the pcurves and
185   // the 3d curves
186
187     // Case of the plane face
188     // NB: in the case 'pointu', no pcurve on the plane surface
189     // and no intersection plane-chamfer are needed
190   Handle(Geom2d_Circle) GCir2dPln;
191   Handle(Geom_Circle) GCirPln;
192   gp_Ax2 CirAx2 = ConAx3.Ax2();
193   CirAx2.SetLocation(PtPl);
194
195   if (!pointu) {
196
197       // intersection plane-chamfer
198     gp_Circ CirPln(CirAx2,Rad);
199     GCirPln = new Geom_Circle(CirPln);
200
201       //pcurve on the plane
202     ElSLib::PlaneParameters(PosPl,Pt ,u,v);
203     gp_Pnt2d p2dPln(u,v);
204     gp_Dir2d d2d(DSp.Dot(PosPl.XDirection()),DSp.Dot(PosPl.YDirection()));
205     gp_Ax22d ax2dPln(pt2dPln, gp_Dir2d(gp_Vec2d(pt2dPln,p2dPln)),d2d);
206     gp_Circ2d cir2dPln(ax2dPln,Rad);
207     GCir2dPln = new Geom2d_Circle(cir2dPln);
208   }
209
210       //pcurve on the chamfer
211   gp_Pnt2d p2dch;
212   if (plandab) 
213     v= -sqrt(Dis1*Dis1+Dis2*Dis2);
214   else 
215     v = sqrt(Dis1*Dis1+Dis2*Dis2);
216   p2dch.SetCoord(0.,v);
217   ElSLib::ConeD1(0.,v,ConAx3,ConRad,SemiAngl,Pt,deru,derv);
218   gp_Lin2d lin2dch(p2dch,gp::DX2d());
219   Handle(Geom2d_Line) GLin2dCh1 = new Geom2d_Line(lin2dch);
220
221       //orientation
222   TopAbs_Orientation trans; 
223   gp_Dir norpl = PosPl.XDirection().Crossed(PosPl.YDirection());
224   toreverse = ( norCon.Dot(norpl) <= 0. );
225   if ((toreverse && plandab) || (!toreverse && !plandab)){ 
226     trans = TopAbs_FORWARD;
227   }
228   else { 
229     trans = TopAbs_REVERSED; 
230   }
231
232
233   if(plandab){
234     Data->ChangeInterferenceOnS1().
235       SetInterference(ChFiKPart_IndexCurveInDS(GCirPln,DStr),
236                       trans,GCir2dPln,GLin2dCh1);
237   }
238   else{
239     Data->ChangeInterferenceOnS2().
240       SetInterference(ChFiKPart_IndexCurveInDS(GCirPln,DStr),
241                       trans,GCir2dPln,GLin2dCh1);
242   }
243
244     // Case of the cylindrical face
245
246       //intersection cylinder-chamfer
247   CirAx2.SetLocation(Or);
248   gp_Circ CirCyl(CirAx2,ConRad);
249   Handle(Geom_Circle) GCirCyl = new Geom_Circle(CirCyl);
250
251       //pcurve on the chamfer
252   p2dch.SetCoord(0.,0.);
253   ElSLib::ConeD1(0.,0.,ConAx3,ConRad,SemiAngl,Pt,deru,derv);
254   lin2dch.SetLocation(p2dch);
255   Handle(Geom2d_Line) GLin2dCh2 = new Geom2d_Line(lin2dch);
256
257       //pcurve on the cylinder
258   norCon.SetXYZ (deru.Crossed(derv).XYZ());
259
260   Pt.SetCoord(Or.X()+ConRad*Dx.X(),
261               Or.Y()+ConRad*Dx.Y(),
262               Or.Z()+ConRad*Dx.Z());
263   ElSLib::Parameters(Cyl,Pt ,u,v);
264   Standard_Real tol = Precision::PConfusion();
265   Standard_Boolean careaboutsens = 0;
266   if(Abs(lu - fu - 2*M_PI) < tol) careaboutsens = 1;
267   if(u >= fu - tol && u < fu) u = fu;
268   if(u <= lu + tol && u > lu) u = lu;
269   if(u < fu || u > lu) u = ChFiKPart_InPeriod(u,fu,fu + 2*M_PI,tol);
270
271   ElSLib::D1(u,v,Cyl,Pt,deru,derv);
272   gp_Dir norcyl = deru.Crossed(derv);
273   gp_Dir2d d2dCyl = gp::DX2d();
274   if( deru.Dot(Dy) < 0. ){
275     d2dCyl.Reverse(); 
276     if(careaboutsens && Abs(fu-u)<tol) u = lu;
277   }
278   else if(careaboutsens && Abs(lu-u)<tol) u = fu;
279   gp_Pnt2d p2dCyl(u,v);
280   gp_Lin2d lin2dCyl(p2dCyl,d2dCyl);
281   Handle(Geom2d_Line) GLin2dCyl = new Geom2d_Line(lin2dCyl);
282
283       //orientation
284   toreverse = ( norCon.Dot(norcyl) <= 0. );
285   if ((toreverse && plandab) || (!toreverse && !plandab) ) {
286     trans = TopAbs_REVERSED;
287   }
288   else {
289     trans = TopAbs_FORWARD;
290   }
291
292
293   if(plandab){
294     Data->ChangeInterferenceOnS2().
295       SetInterference(ChFiKPart_IndexCurveInDS(GCirCyl,DStr),
296                       trans,GLin2dCyl,GLin2dCh2);
297   }
298   else{
299     Data->ChangeInterferenceOnS1().
300       SetInterference(ChFiKPart_IndexCurveInDS(GCirCyl,DStr),
301                       trans,GLin2dCyl,GLin2dCh2);
302   }
303
304   return Standard_True;
305 }
306
307 //=======================================================================
308 //function : MakeChamfer
309 //purpose  : case cylinder/plane or plane/cylinder.
310 //=======================================================================
311
312 Standard_Boolean ChFiKPart_MakeChamfer(TopOpeBRepDS_DataStructure& DStr,
313                                       const Handle(ChFiDS_SurfData)& Data, 
314                                        const gp_Pln& Pln, 
315                                        const gp_Cylinder& Cyl, 
316                                        const Standard_Real /*fu*/,
317                                        const Standard_Real /*lu*/,
318                                        const TopAbs_Orientation Or1,
319                                        const TopAbs_Orientation Or2,
320                                        const Standard_Real dis1,
321                                        const Standard_Real dis2,
322                                        const gp_Lin& Spine, 
323                                        const Standard_Real First, 
324                                        const TopAbs_Orientation Ofpl,
325                                        const Standard_Boolean plandab)
326 {
327   // calculation of the fillet plane.
328   // or1 and or2 permit to determine in which of four sides created by
329   // intersection of 2 surfaces we are
330   //        _|_          Ofpl is orientation of the plane face allowing
331   //         |4          to determine the side of the material
332
333   gp_Pnt OrSpine = ElCLib::Value(First,Spine);
334   gp_Pnt POnCyl, POnPln, OrCyl;
335
336   gp_Dir XDir = Spine.Direction();
337   gp_Ax3 AxPln  = Pln.Position();
338   gp_Dir NorPln = AxPln.XDirection().Crossed(AxPln.YDirection());
339   gp_Dir NorF(NorPln);
340   if (Or1 == TopAbs_REVERSED)
341     {NorF.Reverse();} 
342
343   gp_Ax3 AxCyl = Cyl.Position();
344   // OrCyl is the point on axis of cylinder in the plane normal to the
345   // axis containing OrSpine
346   // Project <OrSpine> onto <AxCyl>
347   gp_XYZ AxLoc = AxCyl.Location().XYZ(); //aLine.Location().XYZ();
348   gp_XYZ AxDir = AxCyl.Direction().XYZ();
349   Standard_Real Parameter = (OrSpine.XYZ() - AxLoc) * AxDir;
350   OrCyl.SetXYZ( AxLoc + Parameter * AxDir );
351  
352   //construction of POnPln
353   gp_Vec VecTranslPln,tmp;
354
355   tmp = gp_Vec(OrSpine,OrCyl);
356   if ((Or2 == TopAbs_FORWARD && Cyl.Direct()) ||
357       (Or2 == TopAbs_REVERSED && !Cyl.Direct()))
358     {tmp.Reverse();}
359
360   VecTranslPln = gp_Vec( XDir.Crossed(NorPln) );
361   if( VecTranslPln.Dot(tmp) <= 0. )
362      {VecTranslPln.Reverse();}
363   VecTranslPln.Multiply(dis1);
364
365   POnPln.SetXYZ( (OrSpine.XYZ()).Added(VecTranslPln.XYZ()) );
366
367   //construction of POnCyl 
368   Standard_Real alpha = ( 2*ASin(dis2*0.5/Cyl.Radius()) );
369 //  gp_Vec VecTranslCyl;
370 //  VecTranslCyl = gp_Vec(OrSpine,OrCyl);
371  
372 //  if ( ( XDir.Crossed(gp_Dir(VecTranslCyl)) ).Dot(NorF) <=0. )
373 //    {VecTranslCyl.Rotate(gp_Ax1(OrSpine,XDir),alpha);}
374 //  else
375 //    {VecTranslCyl.Rotate(gp_Ax1(OrSpine,XDir.Reversed()),alpha);}
376
377 //  POnCyl.SetXYZ( OrCyl.XYZ().Added(VecTranslCyl.XYZ()) );
378
379   gp_Vec  VecCylTransl = gp_Vec(OrCyl,OrSpine);
380
381   if ( ( XDir.Crossed(gp_Dir(VecCylTransl)) ).Dot(NorF) > 0.) {
382     VecCylTransl.Rotate(gp_Ax1(OrCyl,XDir),alpha);
383   }
384   else { 
385     VecCylTransl.Rotate(gp_Ax1(OrCyl,XDir.Reversed()),alpha);}
386
387   POnCyl.SetXYZ( OrCyl.XYZ().Added(VecCylTransl.XYZ()) );
388
389   //construction of chamfer  
390   Standard_Real UOnCyl,VOnCyl,UOnPln,VOnPln;
391   ElSLib::Parameters(Cyl,POnCyl,UOnCyl,VOnCyl);
392   POnCyl = ElSLib::CylinderValue(UOnCyl,VOnCyl,AxCyl,Cyl.Radius());             
393   ElSLib::Parameters(Pln,POnPln,UOnPln,VOnPln);
394   POnPln = ElSLib::PlaneValue(UOnPln,VOnPln,AxPln);
395
396   //construction of YDir to go to face1 from face2.
397   gp_Vec YDir(POnPln,POnCyl);
398   if (!plandab){ 
399     YDir.Reverse();
400   }
401   gp_Ax3 AxCh(POnPln,XDir.Crossed(YDir),XDir);
402
403   Handle(Geom_Plane) Chamfer = new Geom_Plane(AxCh);
404   Data->ChangeSurf(ChFiKPart_IndexSurfaceInDS(Chamfer,DStr));
405
406   // FaceInterferences are loaded with pcurves and curves 3d.
407      //----------- edge plane-Chamfer
408   gp_Pnt2d PPln2d(UOnPln,VOnPln);
409   gp_Dir2d VPln2d(XDir.Dot(AxPln.XDirection()),
410                   XDir.Dot(AxPln.YDirection()));
411   gp_Lin2d Lin2dPln(PPln2d,VPln2d);
412
413   POnPln = ElSLib::Value(UOnPln,VOnPln,Pln);
414   gp_Lin   C3d(POnPln,XDir);
415
416   Standard_Real U,VOnChamfer;
417   ElSLib::PlaneParameters(AxCh,POnPln,U,VOnChamfer);
418   gp_Lin2d LOnChamfer(gp_Pnt2d(U,VOnChamfer),gp::DX2d());
419
420   Handle(Geom_Line)   L3d  = new Geom_Line  (C3d);
421   Handle(Geom2d_Line) LFac = new Geom2d_Line(Lin2dPln);
422   Handle(Geom2d_Line) LFil = new Geom2d_Line(LOnChamfer);
423
424   gp_Dir NorFil=AxCh.Direction();
425   Standard_Boolean toreverse = ( NorFil.Dot(NorPln) <= 0. );
426
427   gp_Dir DirPlnCyl(gp_Vec(POnPln, POnCyl));
428   gp_Dir DirSPln(gp_Vec(OrSpine, POnPln));
429   Standard_Boolean PosChamfPln = DirPlnCyl.Dot(DirSPln) > 0;
430
431   if (PosChamfPln )
432     toreverse = !toreverse; 
433   // It is checked if the orientation of the Chamfer is the same as of the plane
434   if (toreverse)
435     {Data->ChangeOrientation() = TopAbs::Reverse(Ofpl);}
436   else          
437     {Data->ChangeOrientation() = Ofpl;}
438
439   TopAbs_Orientation trans = TopAbs_FORWARD;
440   if ((!plandab && toreverse) || (plandab && !toreverse))
441     {trans=TopAbs_REVERSED;}
442   
443   //trans permits to determine the "material" side on S1(2) limited by L3d
444   if (plandab) 
445     {Data->ChangeInterferenceOnS1().
446      SetInterference(ChFiKPart_IndexCurveInDS(L3d,DStr),trans,LFac,LFil);}
447   else    
448     {Data->ChangeInterferenceOnS2().
449      SetInterference(ChFiKPart_IndexCurveInDS(L3d,DStr),trans,LFac,LFil);}
450   
451      //------------edge cylinder-Chamfer        
452   gp_Pnt2d PCyl2d(UOnCyl,VOnCyl);
453   gp_Dir2d VCyl2d=gp::DY2d();
454   if ( XDir.Dot(AxCyl.Direction())<0 )
455     {VCyl2d.Reverse();}
456   gp_Lin2d Lin2dCyl(PCyl2d,VCyl2d);
457
458   POnCyl = ElSLib::Value(UOnCyl,VOnCyl,Cyl);
459   C3d = gp_Lin(POnCyl,XDir);
460
461   ElSLib::PlaneParameters(AxCh,POnCyl,U,VOnChamfer);
462   LOnChamfer = gp_Lin2d(gp_Pnt2d(U,VOnChamfer),gp::DX2d());
463
464   L3d  = new Geom_Line  (C3d);
465   LFac = new Geom2d_Line(Lin2dCyl);
466   LFil = new Geom2d_Line(LOnChamfer);
467
468   gp_Vec deru,derv;            
469   ElSLib::CylinderD1(UOnCyl,VOnCyl,AxCyl,Cyl.Radius(),POnCyl,deru,derv);
470   gp_Dir NorCyl(deru.Crossed(derv));    
471
472   toreverse = ( NorFil.Dot(NorCyl) <= 0. );
473
474   gp_Dir DirSCyl(gp_Vec(OrSpine, POnCyl));
475   Standard_Boolean PosChamfCyl = DirPlnCyl.Dot(DirSCyl) < 0;
476
477
478   if (PosChamfCyl) 
479      toreverse = !toreverse; 
480
481   trans = TopAbs_REVERSED;
482   if ((!plandab && toreverse) || (plandab && !toreverse))
483     {trans=TopAbs_FORWARD;}
484
485   if (plandab) 
486     Data->ChangeInterferenceOnS2().
487     SetInterference(ChFiKPart_IndexCurveInDS(L3d,DStr),trans,LFac,LFil);
488   else    
489     Data->ChangeInterferenceOnS1().
490     SetInterference(ChFiKPart_IndexCurveInDS(L3d,DStr),trans,LFac,LFil);
491   return Standard_True;
492 }       
493   
494
495
496