0025266: Debug statements in the source are getting flushed on to the console
[occt.git] / src / ChFiKPart / ChFiKPart_ComputeData_FilPlnCyl.cxx
1 // Created on: 1994-02-03
2 // Created by: Isabelle GRIGNON
3 // Copyright (c) 1994-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 #include <ChFiKPart_ComputeData.jxx>
18 #include <Precision.hxx>
19 #include <gp.hxx>
20 #include <gp_Pnt2d.hxx>
21 #include <gp_Dir2d.hxx>
22 #include <gp_Lin2d.hxx>
23 #include <gp_Pnt.hxx>
24 #include <gp_Dir.hxx>
25 #include <gp_Vec.hxx>
26 #include <gp_Lin.hxx>
27 #include <gp_Ax2.hxx>
28 #include <gp_Ax3.hxx>
29 #include <gp_Circ.hxx>
30 #include <gp_Pln.hxx>
31 #include <gp_Cylinder.hxx>
32
33 #include <ElCLib.hxx>
34 #include <ElSLib.hxx>
35
36 #include <Geom2d_Line.hxx>
37 #include <Geom2d_Circle.hxx>
38 #include <Geom_Line.hxx>
39 #include <Geom_Circle.hxx>
40 #include <Geom_ToroidalSurface.hxx>
41 #include <Geom_SphericalSurface.hxx>
42 #include <Geom_CylindricalSurface.hxx>
43 #include <IntAna_QuadQuadGeo.hxx>
44
45 #include <ChFiKPart_ComputeData_Fcts.hxx>
46
47
48 //=======================================================================
49 //function : MakeFillet
50 //purpose  : case cylinder/plane or plane/cylinder.
51 //=======================================================================
52
53 Standard_Boolean ChFiKPart_MakeFillet(TopOpeBRepDS_DataStructure& DStr,
54                                       const Handle(ChFiDS_SurfData)& Data, 
55                                       const gp_Pln& Pln, 
56                                       const gp_Cylinder& Cyl, 
57                                       const Standard_Real fu,
58                                       const Standard_Real lu,
59                                       const TopAbs_Orientation Or1,
60                                       const TopAbs_Orientation Or2,
61                                       const Standard_Real Radius, 
62                                       const gp_Lin& Spine, 
63                                       const Standard_Real First, 
64                                       const TopAbs_Orientation Ofpl,
65                                       const Standard_Boolean plandab)
66 {
67   //calculate the cylinder fillet.
68
69   //plane deviated from radius
70   gp_Ax3 AxPln  = Pln.Position();
71   gp_Dir NorPln = AxPln.XDirection().Crossed(AxPln.YDirection());
72   gp_Dir NorF(NorPln);
73   gp_Ax3 AxCyl = Cyl.Position();
74
75   if (Or1 == TopAbs_REVERSED) { NorF.Reverse(); } 
76   gp_Pln PlanOffset = Pln.Translated(Radius*gp_Vec(NorF));
77
78   // Parallel cylinder
79   Standard_Real    ROff = Cyl.Radius();
80
81   if ((Or2 == TopAbs_FORWARD  &&  Cyl.Direct()) ||
82       (Or2 == TopAbs_REVERSED && !Cyl.Direct()))
83       ROff+=Radius;
84   else if (Radius < ROff)  {
85     ROff-=Radius;
86   }
87   else {
88 #ifdef CHFIKPART_DEB
89     cout<<"the fillet does not pass"<<endl; 
90 #endif
91     return Standard_False;
92   }
93   // intersection of the parallel plane and of the parallel cylinder.
94   gp_Cylinder CylOffset(Cyl.Position(),ROff);
95   IntAna_QuadQuadGeo LInt(PlanOffset,CylOffset,
96                           Precision::Angular(),Precision::Confusion());
97   gp_Pnt OrSpine = ElCLib::Value(First,Spine);
98   gp_Pnt OrFillet;
99   gp_Dir DirFillet;
100   if (LInt.IsDone()) {
101     DirFillet = LInt.Line(1).Direction();
102     gp_Pnt P1 = ElCLib::Value(ElCLib::Parameter
103                               (LInt.Line(1),OrSpine),LInt.Line(1));
104     if(LInt.NbSolutions() == 2){
105       gp_Pnt P2 = ElCLib::Value(ElCLib::Parameter
106                                 (LInt.Line(2),OrSpine),LInt.Line(2));
107       if (P1.SquareDistance(OrSpine) < P2.SquareDistance(OrSpine)) {
108         OrFillet = P1;
109       }
110       else { OrFillet = P2;}
111     }
112     else { OrFillet = P1;}
113   }
114   else {return Standard_False;}
115
116   // Construction fillet
117   if (DirFillet.Dot(Spine.Direction()) < 0.) {DirFillet.Reverse();}
118
119   Standard_Real UOnCyl,VOnCyl,UOnPln,VOnPln;
120   ElSLib::Parameters(Cyl,OrFillet,UOnCyl,VOnCyl);
121   Standard_Real tesp = Precision::Confusion();
122   if(UOnCyl < fu - tesp || UOnCyl > lu + tesp) 
123     UOnCyl = ElCLib::InPeriod(UOnCyl,fu,fu+2*M_PI);
124   ElSLib::Parameters(Pln,OrFillet,UOnPln,VOnPln);
125
126   gp_Vec XDir,OtherDir;
127   XDir     = NorF.Reversed();
128   OtherDir = gp_Dir(gp_Vec(OrFillet,ElSLib::Value(UOnCyl,VOnCyl,Cyl)));
129
130   if (!plandab) {
131     gp_Vec tmp = XDir;
132     XDir     = OtherDir;
133     OtherDir = tmp;
134   }
135   gp_Ax3 AxFil (OrFillet,DirFillet,XDir);
136   // construction YDir to go from face1 to face2.
137   if ((XDir^OtherDir).Dot(DirFillet) < 0.)
138     AxFil.YReverse();
139
140   Handle(Geom_CylindricalSurface) 
141     Fillet = new Geom_CylindricalSurface(AxFil,Radius);
142   Data->ChangeSurf(ChFiKPart_IndexSurfaceInDS(Fillet,DStr));
143
144   // FaceInterferences are loaded with pcurves and curves 3D.
145   // edge plane-Fillet
146   gp_Pnt2d PPln2d(UOnPln,VOnPln);
147   gp_Dir2d VPln2d(DirFillet.Dot(AxPln.XDirection()),
148                   DirFillet.Dot(AxPln.YDirection()));
149   gp_Lin2d Lin2dPln(PPln2d,VPln2d);
150   gp_Pnt   POnPln = ElSLib::Value(UOnPln,VOnPln,Pln);
151   gp_Lin   C3d(POnPln,DirFillet);
152   Standard_Real UOnFillet,V;
153   ElSLib::CylinderParameters(AxFil,Radius,POnPln,UOnFillet,V);
154   if(UOnFillet > M_PI) UOnFillet = 0.;
155   gp_Lin2d LOnFillet(gp_Pnt2d(UOnFillet,V),gp::DY2d());
156   Handle(Geom_Line)   L3d  = new Geom_Line  (C3d);
157   Handle(Geom2d_Line) LFac = new Geom2d_Line(Lin2dPln);
158   Handle(Geom2d_Line) LFil = new Geom2d_Line(LOnFillet);
159   gp_Pnt P;
160   gp_Vec deru,derv;
161   ElSLib::CylinderD1(UOnFillet,V,AxFil,Radius,P,deru,derv);
162   gp_Dir NorFil(deru.Crossed(derv));
163   Standard_Boolean toreverse = ( NorFil.Dot(NorPln) <= 0. );
164   // It is checked if the orientation of the cylinder is the same as of the plane.
165   if (toreverse) {Data->ChangeOrientation() = TopAbs::Reverse(Ofpl);}
166   else           {Data->ChangeOrientation() = Ofpl;}
167
168   TopAbs_Orientation trans; 
169   if ((toreverse && plandab) || (!toreverse && !plandab) ){ 
170     trans = TopAbs_REVERSED; 
171   }
172   else { 
173     trans = TopAbs_FORWARD; 
174   }
175   if (plandab) 
176     Data->ChangeInterferenceOnS1().
177     SetInterference(ChFiKPart_IndexCurveInDS(L3d,DStr),
178                     trans,LFac,LFil);
179   else    
180     Data->ChangeInterferenceOnS2().
181     SetInterference(ChFiKPart_IndexCurveInDS(L3d,DStr),
182                     trans,LFac,LFil);
183
184   // edge cylinder-Fillet.
185   gp_Pnt2d PCyl2d(UOnCyl,VOnCyl);
186   gp_Dir2d DPC = gp::DY2d();
187   if (DirFillet.Dot(AxCyl.Direction()) < 0.) DPC.Reverse();
188   gp_Lin2d Lin2dCyl(PCyl2d,DPC);
189   gp_Pnt POnCyl = ElSLib::Value(UOnCyl,VOnCyl,Cyl);
190   C3d = gp_Lin(POnCyl,DirFillet);
191   ElSLib::CylinderParameters(AxFil,Radius,POnCyl,UOnFillet,V);
192   if(UOnFillet > M_PI) UOnFillet = 0.;
193   LOnFillet = gp_Lin2d(gp_Pnt2d(UOnFillet,V),gp::DY2d());
194   L3d  = new Geom_Line  (C3d);
195   LFac = new Geom2d_Line(Lin2dCyl);
196   LFil = new Geom2d_Line(LOnFillet);  
197   
198   ElSLib::CylinderD1(UOnFillet,V,AxFil,Radius,P,deru,derv);
199   NorFil= gp_Dir(deru.Crossed(derv));
200   ElSLib::CylinderD1(UOnCyl,VOnCyl,AxCyl,Cyl.Radius(),P,deru,derv);
201   gp_Dir NorCyl(deru.Crossed(derv));
202
203   toreverse = ( NorFil.Dot(NorCyl) <= 0. );
204   if ((toreverse && plandab) || (!toreverse && !plandab) ){ 
205     trans = TopAbs_FORWARD; 
206   }
207   else { 
208     trans = TopAbs_REVERSED; 
209   }
210   if (plandab) 
211     Data->ChangeInterferenceOnS2().
212     SetInterference(ChFiKPart_IndexCurveInDS(L3d,DStr),
213                     trans,LFac,LFil);
214   else    
215     Data->ChangeInterferenceOnS1().
216     SetInterference(ChFiKPart_IndexCurveInDS(L3d,DStr),
217                     trans,LFac,LFil);
218   return Standard_True;
219 }
220
221 //=======================================================================
222 //function : MakeFillet
223 //purpose  : case cylinder/plane or plane/cylinder.
224 //=======================================================================
225
226 Standard_Boolean ChFiKPart_MakeFillet(TopOpeBRepDS_DataStructure& DStr,
227                                       const Handle(ChFiDS_SurfData)& Data, 
228                                       const gp_Pln& Pln, 
229                                       const gp_Cylinder& Cyl, 
230                                       const Standard_Real fu,
231                                       const Standard_Real lu,
232                                       const TopAbs_Orientation Or1,
233                                       const TopAbs_Orientation Or2,
234                                       const Standard_Real Radius, 
235                                       const gp_Circ& Spine, 
236                                       const Standard_Real First, 
237                                       const TopAbs_Orientation Ofpl,
238                                       const Standard_Boolean plandab)
239 {
240
241 //calculation of the fillet (torus or sphere).
242   Standard_Boolean c1sphere = Standard_False;
243   gp_Ax3 PosPl = Pln.Position();
244   gp_Dir Dpnat = PosPl.XDirection().Crossed(PosPl.YDirection());
245   gp_Dir Dp = Dpnat;
246   gp_Dir Df = Dp;
247   if (Or1 == TopAbs_REVERSED) { Dp.Reverse(); }
248   if (Ofpl == TopAbs_REVERSED) { Df.Reverse(); }
249
250   gp_Pnt Or = Cyl.Location();
251   Standard_Real u,v;
252   ElSLib::PlaneParameters(PosPl,Or,u,v);
253   gp_Pnt2d c2dPln(u,v);
254   ElSLib::PlaneD0(u,v,PosPl,Or);
255   gp_Pnt cPln = Or;
256   Or.SetCoord(Or.X()+Radius*Dp.X(),
257               Or.Y()+Radius*Dp.Y(),
258               Or.Z()+Radius*Dp.Z());
259   gp_Pnt PtSp;
260   gp_Vec DSp;
261  // Modification for the PtSp found at the wrong side of the sewing edge.
262   gp_Pnt PtSp2;
263   gp_Vec DSp2;
264   Standard_Real acote = 1e-7;
265   ElCLib::D1(First,Spine,PtSp,DSp);
266   ElSLib::Parameters(Cyl,PtSp,u,v);
267   if ((Abs(u)<acote) || (Abs(u-(2*M_PI))<acote)){
268     ElCLib::D1(First+0.2,Spine,PtSp2,DSp2);
269     Standard_Real u2,v2;
270     ElSLib::Parameters(Cyl,PtSp2,u2,v2);
271     if (Abs(u2-u)>M_PI){
272       u = (2*M_PI)-u;
273       PtSp = ElSLib::Value(u,v,Cyl);
274       Standard_Real PR;
275       PR = ElCLib::Parameter(Spine,PtSp);
276       ElCLib::D1(PR,Spine,PtSp2,DSp);
277     }
278   }
279   // end of modif
280   gp_Dir Dx(gp_Vec(Or,PtSp));
281   Dx = Dp.Crossed(Dx.Crossed(Dp));
282   gp_Dir Dy(DSp);
283   gp_Pnt PtCyl;
284   gp_Vec Vu,Vv;
285   ElSLib::D1(u,v,Cyl,PtCyl,Vu,Vv);
286   gp_Dir Dc(Vu.Crossed(Vv));
287   if (Or2 == TopAbs_REVERSED) { Dc.Reverse(); }
288   gp_Dir Dz = Dp;
289   Standard_Real Rad,cylrad = Cyl.Radius();
290   Standard_Boolean dedans = (Dx.Dot(Dc) <= 0.);
291   if(dedans){ 
292     if (!plandab){ Dz.Reverse(); } 
293     Rad = cylrad - Radius;
294     if(Abs(Rad) <= Precision::Confusion()){ c1sphere = Standard_True; }
295     else if(Rad < 0){ 
296 #ifdef CHFIKPART_DEB
297       cout<<"the fillet can't pass"<<endl; 
298 #endif
299       return Standard_False;
300     }
301   }
302   else { 
303     if (plandab){ Dz.Reverse(); } 
304     Rad = cylrad + Radius; 
305   }
306   gp_Ax3 FilAx3(Or,Dz,Dx);
307   if (FilAx3.YDirection().Dot(Dy) <= 0.){ FilAx3.YReverse(); }
308
309   if(c1sphere) {
310     Handle(Geom_SphericalSurface) 
311       gsph = new Geom_SphericalSurface(FilAx3,Radius);
312     Data->ChangeSurf(ChFiKPart_IndexSurfaceInDS(gsph,DStr));
313   }
314   else{
315     Handle(Geom_ToroidalSurface) 
316       gtor = new Geom_ToroidalSurface(FilAx3,Rad,Radius);
317     Data->ChangeSurf(ChFiKPart_IndexSurfaceInDS(gtor,DStr));
318   }
319   
320   // It is checked if the orientation of the fillet is the same as of faces.
321   gp_Pnt P,PP;
322   gp_Vec deru,derv;
323   P.SetCoord(cPln.X()+Rad*Dx.X(),
324              cPln.Y()+Rad*Dx.Y(),
325              cPln.Z()+Rad*Dx.Z());
326   u = 0.;
327   if ((dedans && plandab) || (!dedans && !plandab)){ 
328     if (c1sphere) { v = - M_PI / 2; }
329     else { v = 3 * M_PI / 2; }
330   }
331   else { v = M_PI / 2; }
332   gp_Dir norFil;
333   if(c1sphere){
334     ElSLib::SphereD1(u,v,FilAx3,cylrad,PP,deru,derv);
335     norFil = FilAx3.XDirection().Crossed(FilAx3.YDirection());
336     if(v < 0.) norFil.Reverse();
337   }  
338   else{
339     ElSLib::TorusD1(u,v,FilAx3,Rad,Radius,PP,deru,derv);
340     norFil = gp_Dir(deru.Crossed(derv));
341   }  
342   gp_Pnt2d p2dFil(0.,v);
343   Standard_Boolean toreverse = ( norFil.Dot(Df) <= 0. );
344   if (toreverse) { Data->ChangeOrientation() = TopAbs_REVERSED; }
345   else { Data->ChangeOrientation() = TopAbs_FORWARD; }
346
347   // FaceInterferences are loaded with pcurves and curves 3d.
348
349   // The plane face.
350   Handle(Geom2d_Circle) GCirc2dPln;
351   Handle(Geom_Circle) GCircPln;
352   gp_Ax2 circAx2 = FilAx3.Ax2();
353   if(!c1sphere){
354     ElSLib::PlaneParameters(PosPl,P,u,v);
355     gp_Pnt2d p2dPln(u,v);
356     gp_Dir2d d2d(DSp.Dot(PosPl.XDirection()),DSp.Dot(PosPl.YDirection()));
357     gp_Ax22d ax2dPln(c2dPln,gp_Dir2d(gp_Vec2d(c2dPln,p2dPln)),d2d);
358     gp_Circ2d circ2dPln(ax2dPln,Rad);
359     GCirc2dPln = new Geom2d_Circle(circ2dPln);
360     circAx2.SetLocation(cPln);
361     gp_Circ circPln(circAx2,Rad);
362     GCircPln = new Geom_Circle(circPln);
363   }
364   else {
365     ElSLib::PlaneParameters(PosPl,P,u,v);
366     gp_Pnt2d p2dPln(u,v),pbid;
367     if(plandab){
368       Data->Set2dPoints(p2dPln,p2dPln,pbid,pbid);
369     }
370     else {
371       Data->Set2dPoints(pbid,pbid,p2dPln,p2dPln);
372     }
373   }
374   gp_Lin2d lin2dFil(p2dFil,gp::DX2d());
375   Handle(Geom2d_Line) GLin2dFil1 = new Geom2d_Line(lin2dFil);
376   toreverse = ( norFil.Dot(Dpnat) <= 0. );
377   TopAbs_Orientation trans; 
378   if ((toreverse && plandab) || (!toreverse && !plandab) ){ 
379     trans = TopAbs_FORWARD; 
380   }
381   else { 
382     trans = TopAbs_REVERSED; 
383   }
384   if(plandab){
385     Data->ChangeInterferenceOnS1().
386       SetInterference(ChFiKPart_IndexCurveInDS(GCircPln,DStr),
387                       trans,GCirc2dPln,GLin2dFil1);
388   }
389   else{
390     Data->ChangeInterferenceOnS2().
391       SetInterference(ChFiKPart_IndexCurveInDS(GCircPln,DStr),
392                       trans,GCirc2dPln,GLin2dFil1);
393   }
394
395   // The cylindrical face.
396   P.SetCoord(Or.X()+cylrad*Dx.X(),
397              Or.Y()+cylrad*Dx.Y(),
398              Or.Z()+cylrad*Dx.Z());
399   u = 0.;
400   if (dedans) {
401     if (plandab && !c1sphere) { v = 2 * M_PI; }
402     else { v = 0. ; }
403   }
404   else { v = M_PI; }
405   p2dFil.SetCoord(u,v);
406   if(c1sphere){
407     ElSLib::SphereD1(u,v,FilAx3,cylrad,PP,deru,derv);
408   }  
409   else{
410     ElSLib::TorusD1(u,v,FilAx3,Rad,Radius,PP,deru,derv);
411   }  
412   norFil = deru.Crossed(derv);
413   lin2dFil.SetLocation(p2dFil);
414   Handle(Geom2d_Line) GLin2dFil2 = new Geom2d_Line(lin2dFil);
415   ElSLib::Parameters(Cyl,P,u,v);
416   Standard_Real tol = Precision::PConfusion();
417   Standard_Boolean careaboutsens = 0;
418   if(Abs(lu - fu - 2*M_PI) < tol) careaboutsens = 1;
419   if(u >= fu - tol && u < fu) u = fu;
420   if(u <= lu + tol && u > lu) u = lu;
421   if(u < fu || u > lu) u = ChFiKPart_InPeriod(u,fu,fu + 2*M_PI,tol);
422   ElSLib::D1(u,v,Cyl,PP,deru,derv);
423   gp_Dir norcyl = deru.Crossed(derv);
424   gp_Dir2d d2dCyl = gp::DX2d();
425   if( deru.Dot(Dy) < 0. ){
426     d2dCyl.Reverse(); 
427     if(careaboutsens && Abs(fu-u)<tol) u = lu;
428   }
429   else if(careaboutsens && Abs(lu-u)<tol) u = fu;
430   gp_Pnt2d p2dCyl(u,v);
431   gp_Lin2d lin2dCyl(p2dCyl,d2dCyl);
432   Handle(Geom2d_Line) GLin2dCyl = new Geom2d_Line(lin2dCyl);
433   circAx2.SetLocation(Or);
434   gp_Circ circCyl(circAx2,cylrad);
435   Handle(Geom_Circle) GCircCyl = new Geom_Circle(circCyl);
436   toreverse = ( norFil.Dot(norcyl) <= 0. );
437   if ((toreverse && plandab) || (!toreverse && !plandab) ){ 
438     trans = TopAbs_REVERSED; 
439   }
440   else { 
441     trans = TopAbs_FORWARD; 
442   }
443   if(plandab){
444     Data->ChangeInterferenceOnS2().
445       SetInterference(ChFiKPart_IndexCurveInDS(GCircCyl,DStr),
446                       trans,GLin2dCyl,GLin2dFil2);
447     
448   }
449   else{
450     Data->ChangeInterferenceOnS1().
451       SetInterference(ChFiKPart_IndexCurveInDS(GCircCyl,DStr),
452                       trans,GLin2dCyl,GLin2dFil2);
453   }
454   return Standard_True;
455 }
456
457