0025418: Debug output to be limited to OCC development environment
[occt.git] / src / ChFiKPart / ChFiKPart_ComputeData_ChAsymPlnCon.cxx
1 // Created on: 1998-06-18
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 #include <ChFiKPart_ComputeData.ixx>
18
19 #include <Precision.hxx>
20 #include <gp.hxx>
21 #include <gp_Pnt2d.hxx>
22 #include <gp_Dir2d.hxx>
23 #include <gp_Lin2d.hxx>
24
25 #include <gp_Dir.hxx>
26 #include <gp_Pnt.hxx>
27 #include <gp_Ax2.hxx>
28 #include <gp_Ax3.hxx>
29 #include <gp_Vec.hxx>
30 #include <gp_Circ.hxx>
31
32 #include <ElCLib.hxx>
33 #include <ElSLib.hxx>
34
35 #include <Geom2d_Line.hxx>
36 #include <Geom2d_Circle.hxx>
37 #include <Geom_Circle.hxx>
38 #include <Geom_ConicalSurface.hxx>
39 #include <Geom_CylindricalSurface.hxx>
40
41 #include <ChFiKPart_ComputeData_Fcts.hxx>
42
43
44 //=======================================================================
45 //function : MakeChAsym
46 //purpose  : Compute the chamfer in the particular case Plane/Cone or 
47 //           Cylinder/Plane
48 //           Compute the SurfData <Data> of the chamfer build on the <Spine>
49 //           between the plane <Pln> and the cone <Con>, with the 
50 //           distances <Dis1> on <Pln> and <Dis2> on <Con>.
51 //           <Or1> and <Or2> are the orientations of <Pln> and <Con>
52 //           and <Ofpl> this of the face carried by <Pln>.
53 //           <First> is the start point on the <Spine>
54 //           <Plandab> is equal to True if the plane is the surface S1
55 //           <fu> and <lu> are the first and last u parameters of the
56 //           cone
57 //out      : True if the chanfer has been computed
58 //           False else
59 //=======================================================================
60
61 Standard_Boolean ChFiKPart_MakeChAsym(TopOpeBRepDS_DataStructure& DStr,
62                                       const Handle(ChFiDS_SurfData)& Data, 
63                                       const gp_Pln& Pln, 
64                                       const gp_Cone& Con, 
65                                       const Standard_Real fu,
66                                       const Standard_Real lu,
67                                       const TopAbs_Orientation Or1,
68                                       const TopAbs_Orientation Or2,
69                                       const Standard_Real Dis, 
70                                       const Standard_Real Angle,
71                                       const gp_Circ& Spine, 
72                                       const Standard_Real First, 
73                                       const TopAbs_Orientation Ofpl,
74                                       const Standard_Boolean plandab,
75                                       const Standard_Boolean DisOnP)
76 {
77   // Compute the chamfer surface(cone)
78   gp_Ax3 PosPl = Pln.Position();
79   gp_Dir Dpl = PosPl.XDirection().Crossed(PosPl.YDirection());
80   gp_Dir norf = Dpl;
81   if (Ofpl == TopAbs_REVERSED ) norf.Reverse();
82   if ( Or1 == TopAbs_REVERSED ) Dpl.Reverse();
83
84   // compute the origin of the conical chamfer PtPl
85   gp_Pnt Or = Con.Location();
86   Standard_Real u,v;
87   ElSLib::PlaneParameters(PosPl,Or,u,v);
88   gp_Pnt2d pt2dPln(u,v);
89   ElSLib::PlaneD0(u,v,PosPl,Or);
90   gp_Pnt PtPl = Or;
91
92   gp_Pnt PtSp;
93   gp_Vec DSp;
94   ElCLib::D1(First,Spine,PtSp,DSp);
95   gp_Dir Dx(gp_Vec(PtPl,PtSp));
96
97   //compute the normal to the cone in PtSp
98   gp_Vec deru,derv;
99   gp_Pnt PtCon;
100   ElSLib::Parameters(Con,PtSp,u,v);
101   ElSLib::D1(u,v,Con,PtCon ,deru,derv);
102   gp_Dir Dcon( deru.Crossed(derv) );
103   if ( Or2 == TopAbs_REVERSED ) Dcon.Reverse();
104   
105   Standard_Boolean dedans = ( Dx.Dot(Dcon) <= 0.);
106   Standard_Boolean ouvert = ( Dpl.Dot(Dcon) >= 0.);
107
108     // variables used to compute the semiangle of the chamfer
109   Standard_Real angCon = Con.SemiAngle();
110   Standard_Real move;
111   Standard_Real ChamfRad,SemiAngl;
112   Standard_Boolean pointu = Standard_False;
113   Standard_Real dis;
114   Standard_Boolean iscylinder = Standard_False;
115   Standard_Boolean isConPar   = Standard_False;
116
117   if ( (plandab && DisOnP) || (!plandab && !DisOnP) ) {
118     Standard_Real tgang = Tan(Angle), Dis11;
119     Standard_Real tgCon = Abs(Tan(angCon));
120     if (ouvert) { 
121       move  = Dis * tgang / (1. - tgCon * tgang);
122       Dis11 = move * tgCon;
123       dis   = Dis + Dis11;
124     }
125     else {
126       move  = Dis * tgang / (1. + tgCon * tgang);
127       Dis11 = move * tgCon;
128       dis   = Dis - Dis11;
129     }
130
131     // compute the parameters of the conical chamfer
132     if (dedans) {
133       ChamfRad = Spine.Radius() - Dis;
134       if ( Abs(ChamfRad) < Precision::Confusion() ) pointu = Standard_True;
135       if( ChamfRad < 0 ) {
136 #ifdef OCCT_DEBUG
137         cout<<"the chamfer can't pass"<<endl;
138 #endif
139         return Standard_False;
140       }
141       SemiAngl = M_PI / 2. - Angle;      
142     }
143     else {
144       ChamfRad = Spine.Radius() + Dis;
145       SemiAngl = Angle - M_PI / 2.;
146     }
147
148     if (ouvert) {
149       if (Abs(angCon) - Abs(SemiAngl) > -Precision::Confusion() ) {
150 #ifdef OCCT_DEBUG
151         cout<<"wrong choice of angle for the chamfer"<<endl;
152 #endif
153         return Standard_False; 
154       } 
155     }
156   } 
157   else {
158     Standard_Real Dis1;
159     move = Dis * Cos(angCon);
160     if (ouvert) {
161       SemiAngl =  Abs(angCon) + Angle;
162
163       if ( (M_PI / 2. - SemiAngl) < Precision::Confusion() ) {
164 #ifdef OCCT_DEBUG
165         cout <<"wrong choice of angle for the chamfer"<<endl;
166 #endif
167         return Standard_False;
168       }
169       Dis1 =  move * Tan(SemiAngl) - Dis * Abs(Sin(angCon));
170
171       if (!dedans) SemiAngl = -SemiAngl;
172
173     }
174     else {
175       SemiAngl =  Abs(angCon) - Angle;
176
177       if ( Abs(SemiAngl) < Precision::Confusion() ) {
178         iscylinder = Standard_True;
179         Dis1       = Dis * Abs(Sin(angCon));
180       }
181       else {        
182         Dis1 = Dis * Abs(Sin(angCon)) - move * Tan(SemiAngl);
183       }
184
185       if (SemiAngl > Precision::Confusion())
186         isConPar = Standard_True;
187
188       if (dedans) SemiAngl = -SemiAngl;
189
190     }
191
192     // compute the parameters of the conical chamfer
193     if (dedans) {
194        ChamfRad = Spine.Radius() - Dis1;
195
196       if ( Abs(ChamfRad) < Precision::Confusion() ) pointu = Standard_True;
197       if( ChamfRad < 0 ) {
198 #ifdef OCCT_DEBUG
199         cout<<"the chamfer can't pass"<<endl;
200 #endif
201         return Standard_False;
202       }
203     }
204     else {
205       ChamfRad = Spine.Radius() + Dis1;
206       //Dpl.Reverse();
207     }
208
209     if (ouvert) 
210       dis = Dis1 + Dis * Abs(Sin(angCon));
211     else 
212       dis = Dis1 - Dis * Abs(Sin(angCon));
213   }
214
215   Or.SetCoord( Or.X()+ move*Dpl.X(),
216                Or.Y()+ move*Dpl.Y(),
217                Or.Z()+ move*Dpl.Z());
218   gp_Pnt Pt(Or.X()+dis*PosPl.XDirection().X(),
219             Or.Y()+dis*PosPl.XDirection().Y(),
220             Or.Z()+dis*PosPl.XDirection().Z());
221
222   gp_Ax3 ChamfAx3(PtPl,Dpl,Dx);
223
224
225   if (iscylinder) {
226     Handle (Geom_CylindricalSurface)
227       gcyl = new Geom_CylindricalSurface( ChamfAx3, ChamfRad );
228     
229     // changes due to the fact the parameters of the chamfer must go increasing
230     // from surface S1 to surface S2
231     if (!plandab) {
232       gcyl->VReverse();// be carefull : the SemiAngle was changed
233       ChamfAx3 = gcyl->Position();
234     }
235
236     // changes due to the fact we have reversed the V direction of 
237     // parametrization
238     if (ChamfAx3.YDirection().Dot(DSp) <= 0.) {
239       ChamfAx3.YReverse();
240       gcyl->SetPosition(ChamfAx3);
241     }
242
243     Data->ChangeSurf(ChFiKPart_IndexSurfaceInDS(gcyl,DStr));
244
245     Standard_Boolean torevcha = !ChamfAx3.Direct();
246     gp_Dir cylaxe = (ChamfAx3.Axis()).Direction();
247     torevcha = ( (torevcha  && !plandab) || (!torevcha  && plandab));
248
249     if (torevcha) cylaxe.Reverse();
250     Standard_Boolean toreverse = (norf.Dot(cylaxe) < 0.);
251    
252     if ((toreverse && dedans) || (!toreverse && !dedans))
253       Data->ChangeOrientation() = TopAbs_REVERSED;
254     else
255       Data->ChangeOrientation() = TopAbs_FORWARD; 
256         
257     //we load the faceInterference with the pcurves and
258     // the 3d curves
259     
260     // Case of the plane face
261     // NB: in the case 'pointu', no pcurve on the plane surface
262     // and no intersection plane-chamfer are needed
263     
264     // intersection plane-chamfer
265     Handle(Geom_Circle) GCirPln;
266     Handle(Geom2d_Circle) GCir2dPln;
267     gp_Ax2 CirAx2 = ChamfAx3.Ax2();
268     CirAx2.SetLocation(PtPl);
269
270     Pt.SetCoord(PtPl.X()+ChamfRad*Dx.X(),
271                 PtPl.Y()+ChamfRad*Dx.Y(),
272                 PtPl.Z()+ChamfRad*Dx.Z());
273     gp_Circ CirPln(CirAx2,ChamfRad);
274     GCirPln = new Geom_Circle(CirPln);
275     
276     //pcurve on the plane
277     ElSLib::PlaneParameters(PosPl,Pt ,u,v);
278     gp_Pnt2d p2dPln(u,v);
279     gp_Dir2d d2d(DSp.Dot(PosPl.XDirection()),DSp.Dot(PosPl.YDirection()));
280     gp_Ax22d ax2dPln(pt2dPln, gp_Dir2d(gp_Vec2d(pt2dPln,p2dPln)),d2d);
281     gp_Circ2d cir2dPln(ax2dPln,ChamfRad);
282     GCir2dPln = new Geom2d_Circle(cir2dPln);
283     
284     //pcurve on chamfer
285     gp_Pnt2d p2dch;
286     p2dch.SetCoord(0.,0.);
287     // ElSLib::CylinderD1(0.,0.,ChamfAx3,ChamfRad,Pt,deru,derv);
288     gp_Lin2d lin2dch(p2dch,gp::DX2d());
289     Handle(Geom2d_Line) GLin2dCh1 = new Geom2d_Line(lin2dch);
290     
291     //orientation
292     TopAbs_Orientation trans; 
293     gp_Dir norpl = PosPl.XDirection().Crossed(PosPl.YDirection());
294     toreverse = (norpl.Dot(cylaxe) < 0.);
295
296    toreverse = (toreverse && plandab) || (!toreverse && !plandab);
297  
298    if ((toreverse && dedans) || (!toreverse && !dedans)) { 
299       trans = TopAbs_FORWARD;
300     }
301     else { 
302       trans = TopAbs_REVERSED; 
303     }
304
305     if (plandab) { 
306       Data->ChangeInterferenceOnS1().
307         SetInterference(ChFiKPart_IndexCurveInDS(GCirPln,DStr),
308                         trans,GCir2dPln,GLin2dCh1);
309     }
310     else {
311       Data->ChangeInterferenceOnS2().
312         SetInterference(ChFiKPart_IndexCurveInDS(GCirPln,DStr),
313                         trans,GCir2dPln,GLin2dCh1);
314     }
315
316     // Case of the conical face
317     
318     //intersection cone-chamfer
319     Standard_Real Rad;
320     if (dedans)
321       Rad = ChamfRad + dis;
322     else
323       Rad = ChamfRad - dis;
324     
325     CirAx2.SetLocation(Or);
326     gp_Circ CirCon(CirAx2, Rad);
327     Handle(Geom_Circle) GCirCon = new Geom_Circle(CirCon);  
328     
329     //pcurve on chamfer
330     if (plandab)
331       v = sqrt(dis*dis + move*move);
332     else
333       v = - sqrt(dis*dis + move*move);
334     p2dch.SetCoord(0.,v);
335     ElSLib::CylinderD1(0.,v,ChamfAx3,ChamfRad,Pt,deru,derv);
336     lin2dch.SetLocation(p2dch);
337     Handle(Geom2d_Line) GLin2dCh2 = new Geom2d_Line(lin2dch);
338     
339     //pcurve on cone
340     Pt.SetCoord(Or.X()+Rad*Dx.X(),
341                 Or.Y()+Rad*Dx.Y(),
342                 Or.Z()+Rad*Dx.Z());
343     ElSLib::Parameters(Con,Pt ,u,v);
344     Standard_Real tol = Precision::PConfusion();
345     if(u >= 2*M_PI - tol && u <= 2*M_PI) u = 0.;
346     if(u >= fu - tol && u < fu) u = fu;
347     if(u <= lu + tol && u > lu) u = lu;
348     if(u < fu || u > lu) u = ElCLib::InPeriod(u,fu,fu + 2*M_PI);
349     ElSLib::D1(u,v,Con,Pt,deru,derv);
350     gp_Pnt2d p2dCon(u,v);
351     gp_Dir2d d2dCon;
352     if ( deru.Dot(DSp)<=0. )
353       d2dCon = - gp::DX2d();
354     else
355       d2dCon = gp::DX2d();
356     gp_Lin2d lin2dCon(p2dCon,d2dCon);
357     Handle(Geom2d_Line) GLin2dCon = new Geom2d_Line(lin2dCon);
358     
359     //orientation
360     gp_Dir norcon = deru.Crossed(derv);
361
362     gp_Dir DirCon   = (Con.Axis()).Direction();
363     if (angCon > Precision::Confusion()) DirCon.Reverse();
364     Standard_Boolean torevcon = ( norcon.Dot(DirCon) < 0. );
365
366     if ((torevcon && dedans) || (!torevcon && !dedans) ) {
367       trans = TopAbs_REVERSED;
368     }
369     else {
370       trans = TopAbs_FORWARD;
371     }
372     
373     if(plandab){
374       Data->ChangeInterferenceOnS2().
375         SetInterference(ChFiKPart_IndexCurveInDS(GCirCon,DStr),
376                         trans,GLin2dCon,GLin2dCh2);
377     }
378     else {
379       Data->ChangeInterferenceOnS1().
380         SetInterference(ChFiKPart_IndexCurveInDS(GCirCon,DStr),
381                         trans,GLin2dCon,GLin2dCh2);
382     }
383   }
384   else { 
385     Handle (Geom_ConicalSurface)
386       gcon = new Geom_ConicalSurface( ChamfAx3, SemiAngl, ChamfRad );
387     
388     // changes due to the fact the parameters of the chamfer must go increasing
389     // from surface S1 to surface S2
390     if (!plandab) {
391       gcon->VReverse();// be carefull : the SemiAngle was changed
392       ChamfAx3 = gcon->Position();
393       SemiAngl = gcon->SemiAngle();
394     }
395
396     // changes due to the fact we have reversed the V direction of 
397     // parametrization
398     if (ChamfAx3.YDirection().Dot(DSp) <= 0.) {
399       ChamfAx3.YReverse();
400       gcon->SetPosition(ChamfAx3);
401     }
402
403     Data->ChangeSurf(ChFiKPart_IndexSurfaceInDS(gcon,DStr));
404
405     //compute the chamfer's orientation according to the orientation
406     // of the faces
407     
408     //search the normal to the conical chamfer
409     gp_Pnt P;
410     u = 0.;
411     if (plandab)
412       v = sqrt(dis*dis + move*move);
413     else
414       v = - sqrt(dis*dis + move*move);
415
416     ElSLib::ConeD1(u,v,ChamfAx3,ChamfRad,SemiAngl,P,deru,derv);
417     gp_Dir norchamf(deru.Crossed(derv));
418     
419     Standard_Boolean toreverse = (norf.Dot(norchamf) < 0.);
420
421     if (isConPar)  toreverse = !toreverse;
422     
423     if (toreverse) 
424       Data->ChangeOrientation() = TopAbs_REVERSED;
425     else
426       Data->ChangeOrientation() = TopAbs_FORWARD;
427
428     //we load the faceInterference with the pcurves and
429     // the 3d curves
430     
431     // Case of the plane face
432     // NB: in the case 'pointu', no pcurve on the plane surface
433     // and no intersection plane-chamfer are needed
434     
435     // intersection plane-chamfer
436     Handle(Geom_Circle) GCirPln;
437     Handle(Geom2d_Circle) GCir2dPln;
438     gp_Ax2 CirAx2 = ChamfAx3.Ax2();
439     CirAx2.SetLocation(PtPl);
440     
441     if (!pointu) {
442       Pt.SetCoord(PtPl.X()+ChamfRad*Dx.X(),
443                   PtPl.Y()+ChamfRad*Dx.Y(),
444                   PtPl.Z()+ChamfRad*Dx.Z());
445       gp_Circ CirPln(CirAx2,ChamfRad);
446       GCirPln = new Geom_Circle(CirPln);
447       
448       //pcurve on the plane
449       ElSLib::PlaneParameters(PosPl,Pt ,u,v);
450       gp_Pnt2d p2dPln(u,v);
451       gp_Dir2d d2d(DSp.Dot(PosPl.XDirection()),DSp.Dot(PosPl.YDirection()));
452       gp_Ax22d ax2dPln(pt2dPln, gp_Dir2d(gp_Vec2d(pt2dPln,p2dPln)),d2d);
453       gp_Circ2d cir2dPln(ax2dPln,ChamfRad);
454       GCir2dPln = new Geom2d_Circle(cir2dPln);
455     }
456
457     //pcurve on chamfer
458     gp_Pnt2d p2dch;
459     p2dch.SetCoord(0.,0.);
460     ElSLib::ConeD1(0.,0.,ChamfAx3,ChamfRad,SemiAngl,Pt,deru,derv);
461     gp_Lin2d lin2dch(p2dch,gp::DX2d());
462     Handle(Geom2d_Line) GLin2dCh1 = new Geom2d_Line(lin2dch);
463     
464     //orientation
465     TopAbs_Orientation trans; 
466     gp_Dir norpl = PosPl.XDirection().Crossed(PosPl.YDirection());
467     if (!pointu)
468       norchamf.SetXYZ (deru.Crossed(derv).XYZ());
469     toreverse = ( norchamf.Dot(norpl) <= 0. );
470
471     if (isConPar)  toreverse = !toreverse;
472
473     if ((toreverse && plandab) || (!toreverse && !plandab)){ 
474       trans = TopAbs_FORWARD;
475     }
476     else { 
477       trans = TopAbs_REVERSED; 
478     }
479
480     if (plandab) { 
481       Data->ChangeInterferenceOnS1().
482         SetInterference(ChFiKPart_IndexCurveInDS(GCirPln,DStr),
483                         trans,GCir2dPln,GLin2dCh1);
484     }
485     else {
486       Data->ChangeInterferenceOnS2().
487         SetInterference(ChFiKPart_IndexCurveInDS(GCirPln,DStr),
488                         trans,GCir2dPln,GLin2dCh1);
489     }
490
491     // Case of the conical face
492     
493     //intersection cone-chamfer
494     Standard_Real Rad;
495     if (dedans)
496       Rad = ChamfRad + dis;
497     else
498       Rad = ChamfRad - dis;
499     
500     CirAx2.SetLocation(Or);
501     gp_Circ CirCon(CirAx2, Rad);
502     Handle(Geom_Circle) GCirCon = new Geom_Circle(CirCon);  
503     
504     //pcurve on chamfer
505     if (plandab)
506       v = sqrt(dis*dis + move*move);
507     else
508       v = - sqrt(dis*dis + move*move);
509     p2dch.SetCoord(0.,v);
510     ElSLib::ConeD1(0.,v,ChamfAx3,ChamfRad,SemiAngl,Pt,deru,derv);
511     lin2dch.SetLocation(p2dch);
512     Handle(Geom2d_Line) GLin2dCh2 = new Geom2d_Line(lin2dch);
513     
514     //pcurve on cone
515     norchamf.SetXYZ (deru.Crossed(derv).XYZ());
516
517     Pt.SetCoord(Or.X()+Rad*Dx.X(),
518                 Or.Y()+Rad*Dx.Y(),
519                 Or.Z()+Rad*Dx.Z());
520     ElSLib::Parameters(Con,Pt ,u,v);
521     Standard_Real tol = Precision::PConfusion();
522     if (u >= 2*M_PI - tol && u <= 2*M_PI) u = 0.;
523     if (u >= fu - tol && u < fu) u = fu;
524     if (u <= lu + tol && u > lu) u = lu;
525     if (u < fu || u > lu) u = ElCLib::InPeriod(u,fu,fu + 2*M_PI);
526     ElSLib::D1(u,v,Con,Pt,deru,derv);
527     gp_Pnt2d p2dCon(u,v);
528     gp_Dir2d d2dCon;
529     if ( deru.Dot(DSp)<=0. )
530       d2dCon = - gp::DX2d();
531     else
532       d2dCon = gp::DX2d();
533     gp_Lin2d lin2dCon(p2dCon,d2dCon);
534     Handle(Geom2d_Line) GLin2dCon = new Geom2d_Line(lin2dCon);
535     
536     //orientation
537     gp_Dir norcon = deru.Crossed(derv);
538
539     gp_Dir DirCon   = (Con.Axis()).Direction();
540     gp_Dir DirChamf = (gcon->Axis()).Direction();
541     if (angCon > Precision::Confusion()) DirCon.Reverse();
542     if (SemiAngl > Precision::Confusion()) DirChamf.Reverse();   
543
544     Standard_Boolean torevcon = ( norcon.Dot(DirCon) > 0. );
545     Standard_Boolean torevcha = ( norchamf.Dot(DirChamf) > 0. );
546
547     toreverse = ( (torevcon && !torevcha) || (!torevcon && torevcha) );
548
549     if ((toreverse && plandab) || (!toreverse && !plandab) ) {
550       trans = TopAbs_REVERSED;
551     }
552     else {
553       trans = TopAbs_FORWARD;
554     } 
555
556     if(plandab){
557       Data->ChangeInterferenceOnS2().
558         SetInterference(ChFiKPart_IndexCurveInDS(GCirCon,DStr),
559                         trans,GLin2dCon,GLin2dCh2);
560     }
561     else {
562       Data->ChangeInterferenceOnS1().
563         SetInterference(ChFiKPart_IndexCurveInDS(GCirCon,DStr),
564                         trans,GLin2dCon,GLin2dCh2);
565     }
566     
567   }    
568   return Standard_True;
569 }
570
571
572
573