0023024: Update headers of OCCT files
[occt.git] / src / ChFiKPart / ChFiKPart_ComputeData_ChPlnCyl.cxx
CommitLineData
b311480e 1// Created on: 1995-05-19
2// Created by: Flore Lantheaume
3// Copyright (c) 1995-1999 Matra Datavision
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
6// The content of this file is subject to the Open CASCADE Technology Public
7// License Version 6.5 (the "License"). You may not use the content of this file
8// except in compliance with the License. Please obtain a copy of the License
9// at http://www.opencascade.org and read it completely before using this file.
10//
11// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13//
14// The Original Code and all software distributed under the License is
15// distributed on an "AS IS" basis, without warranty of any kind, and the
16// Initial Developer hereby disclaims all such warranties, including without
17// limitation, any warranties of merchantability, fitness for a particular
18// purpose or non-infringement. Please see the License for the specific terms
19// and conditions governing the rights and limitations under the License.
20
7fd59977 21
22
23#include <ChFiKPart_ComputeData.jxx>
24
25#include <Precision.hxx>
26#include <gp.hxx>
27#include <gp_Ax22d.hxx>
28#include <gp_Pnt2d.hxx>
29#include <gp_Dir2d.hxx>
30#include <gp_Circ2d.hxx>
31#include <gp_Pnt.hxx>
32#include <gp_Dir.hxx>
33#include <gp_Vec.hxx>
34#include <gp_Circ.hxx>
35#include <gp_Ax2.hxx>
36#include <gp_Ax3.hxx>
37#include <gp_Lin2d.hxx>
38
39#include <ElCLib.hxx>
40#include <ElSLib.hxx>
41
42#include <Geom_ConicalSurface.hxx>
43#include <Geom2d_Line.hxx>
44#include <Geom_Line.hxx>
45#include <Geom2d_Circle.hxx>
46#include <Geom_Circle.hxx>
47#include <Geom_Plane.hxx>
48#include <IntAna_QuadQuadGeo.hxx>
49
50#include <ChFiKPart_ComputeData_Fcts.hxx>
51
52
53//pour tester
54
55#include <Geom_CylindricalSurface.hxx>
56
57
58//=======================================================================
59//function : MakeChamfer
60//purpose : Compute the chamfer in the particular case Plane/Cylinder
61// or Cylinder/Plane
62// Compute the SurfData <Data> of the chamfer build on the <Spine>
63// between the plane <Pln> and the cylinder <Cyl>, with the
64// distances <Dis1> on <Pln> and <Dis2> on <Cyl>.
65// <Or1> and <Or2> are the orientations of <Pln> and <Cyl>
66// and <Ofpl> this of the face carried by <Pln>.
67// <First> is the start point on the <Spine>
68// <Plandab> is equal to True if the plane is the surface S1
69// <fu> and <lu> are the first and last u parameters of the
70// cylinder
71//out : True if the chanfer has been computed
72// False else
73//=======================================================================
74
75Standard_Boolean ChFiKPart_MakeChamfer(TopOpeBRepDS_DataStructure& DStr,
76 const Handle(ChFiDS_SurfData)& Data,
77 const gp_Pln& Pln,
78 const gp_Cylinder& Cyl,
79 const Standard_Real fu,
80 const Standard_Real lu,
81 const TopAbs_Orientation Or1,
82 const TopAbs_Orientation Or2,
83 const Standard_Real Dis1,
84 const Standard_Real Dis2,
85 const gp_Circ& Spine,
86 const Standard_Real First,
87 const TopAbs_Orientation Ofpl,
88 const Standard_Boolean plandab)
89{
90
91 // compute the chamfer surface(cone)
92
93 // compute the normals to the plane surface & to the plane face
94 gp_Ax3 PosPl = Pln.Position();
95 gp_Dir Dpl = PosPl.XDirection().Crossed(PosPl.YDirection());
96 gp_Dir norf = Dpl;
97 if ( Ofpl == TopAbs_REVERSED) norf.Reverse();
98 if (Or1 == TopAbs_REVERSED) Dpl.Reverse();
99
100 // compute the origin Or of the cone
101 gp_Pnt Or = Cyl.Location();
102 Standard_Real u,v;
103 ElSLib::PlaneParameters(PosPl,Or,u,v);
104 gp_Pnt2d pt2dPln(u,v);
105 ElSLib::PlaneD0(u,v,PosPl,Or);
106 gp_Pnt PtPl = Or; // projection of the cylinder origin
107 //on the plane
108
109 gp_Pnt PtSp;//start 3d point on the Spine
110 gp_Vec DSp; //tangent vector to the spine on PtSp
111 ElCLib::D1(First,Spine,PtSp,DSp);
112 gp_Dir Dx(gp_Vec(Or,PtSp));
113 gp_Dir Dy(DSp);
114 ElSLib::Parameters(Cyl,PtSp,u,v);
115 gp_Pnt PtCyl;//point on the cylinder and on the Spine
116 gp_Vec Vu,Vv;
117 ElSLib::D1(u,v,Cyl,PtCyl,Vu,Vv);
118 gp_Dir Dcyl(Vu.Crossed(Vv));//normal to the cylinder in PtSp
119 if (Or2 == TopAbs_REVERSED) Dcyl.Reverse();
120 Standard_Boolean dedans = ( Dcyl.Dot(Dx) <= 0.);
121
122 Standard_Boolean pointu = Standard_False;
123 Standard_Real ConRad, Rad, SemiAngl ;
124 Or.SetCoord(Or.X()+Dis2*Dpl.X(),
125 Or.Y()+Dis2*Dpl.Y(),
126 Or.Z()+Dis2*Dpl.Z());
127
128 // variables used to compute the semiangle of the cone
129 gp_Dir Vec1(Or.X()-PtPl.X(), Or.Y()-PtPl.Y(), Or.Z()-PtPl.Z());
130 gp_Pnt Pt(Or.X()+Dis1*PosPl.XDirection().X(),
131 Or.Y()+Dis1*PosPl.XDirection().Y(),
132 Or.Z()+Dis1*PosPl.XDirection().Z());
133 gp_Dir Vec2( Pt.X()-PtPl.X(), Pt.Y()-PtPl.Y(), Pt.Z()-PtPl.Z());
134
135 // compute the parameters of the conical surface
136 if (dedans) {
137 Rad = Cyl.Radius()- Dis1;
138 if ( Abs(Rad) <= Precision::Confusion() ) pointu = Standard_True;
139 if(Rad < 0 ) {
81bba717 140 cout<<"the chamfer can't pass"<<endl;
7fd59977 141 return Standard_False;
142 }
143 }
144 else {
145 Rad = Cyl.Radius()+Dis1;
146 gp_Dir Dplr = Dpl.Reversed();
147 Dpl = Dplr;
148 }
149 ConRad = Cyl.Radius();
150 SemiAngl = Vec1.Angle(Vec2);
151 gp_Ax3 ConAx3(Or,Dpl,Dx);
152
153 Handle (Geom_ConicalSurface)
154 gcon = new Geom_ConicalSurface( ConAx3, SemiAngl, ConRad );
155
156 // changes due to the fact the parameters of the chamfer must go increasing
157 // from surface S1 to surface S2
158 if ( (dedans && !plandab) || (!dedans && plandab) ) {
159 gcon->VReverse();// be carefull : the SemiAngle was changed
160 ConAx3 = gcon->Position();
161 SemiAngl = gcon->SemiAngle();
162 }
163
164 // changes due to the fact we have reversed the V direction of
165 // parametrization
166 if (ConAx3.YDirection().Dot(DSp) <= 0.) {
167 ConAx3.YReverse();
168 gcon->SetPosition(ConAx3);
169 }
170
171 Data->ChangeSurf(ChFiKPart_IndexSurfaceInDS(gcon,DStr));
172
173
174 // compute the chamfer's orientation according to the orientation
175 // of the faces
176
177 //search the normal to the cone
178
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
205 // intersection plane-chamfer
206 gp_Circ CirPln(CirAx2,Rad);
207 GCirPln = new Geom_Circle(CirPln);
208
209 //pcurve on the plane
210 ElSLib::PlaneParameters(PosPl,Pt ,u,v);
211 gp_Pnt2d p2dPln(u,v);
212 gp_Dir2d d2d(DSp.Dot(PosPl.XDirection()),DSp.Dot(PosPl.YDirection()));
213 gp_Ax22d ax2dPln(pt2dPln, gp_Dir2d(gp_Vec2d(pt2dPln,p2dPln)),d2d);
214 gp_Circ2d cir2dPln(ax2dPln,Rad);
215 GCir2dPln = new Geom2d_Circle(cir2dPln);
216 }
217
218 //pcurve on the chamfer
219 gp_Pnt2d p2dch;
220 if (plandab)
221 v= -sqrt(Dis1*Dis1+Dis2*Dis2);
222 else
223 v = sqrt(Dis1*Dis1+Dis2*Dis2);
224 p2dch.SetCoord(0.,v);
225 ElSLib::ConeD1(0.,v,ConAx3,ConRad,SemiAngl,Pt,deru,derv);
226 gp_Lin2d lin2dch(p2dch,gp::DX2d());
227 Handle(Geom2d_Line) GLin2dCh1 = new Geom2d_Line(lin2dch);
228
229 //orientation
230 TopAbs_Orientation trans;
231 gp_Dir norpl = PosPl.XDirection().Crossed(PosPl.YDirection());
232 toreverse = ( norCon.Dot(norpl) <= 0. );
233 if ((toreverse && plandab) || (!toreverse && !plandab)){
234 trans = TopAbs_FORWARD;
235 }
236 else {
237 trans = TopAbs_REVERSED;
238 }
239
240
241 if(plandab){
242 Data->ChangeInterferenceOnS1().
243 SetInterference(ChFiKPart_IndexCurveInDS(GCirPln,DStr),
244 trans,GCir2dPln,GLin2dCh1);
245 }
246 else{
247 Data->ChangeInterferenceOnS2().
248 SetInterference(ChFiKPart_IndexCurveInDS(GCirPln,DStr),
249 trans,GCir2dPln,GLin2dCh1);
250 }
251
252 // Case of the cylindrical face
253
254 //intersection cylinder-chamfer
255 CirAx2.SetLocation(Or);
256 gp_Circ CirCyl(CirAx2,ConRad);
257 Handle(Geom_Circle) GCirCyl = new Geom_Circle(CirCyl);
258
259 //pcurve on the chamfer
260 p2dch.SetCoord(0.,0.);
261 ElSLib::ConeD1(0.,0.,ConAx3,ConRad,SemiAngl,Pt,deru,derv);
262 lin2dch.SetLocation(p2dch);
263 Handle(Geom2d_Line) GLin2dCh2 = new Geom2d_Line(lin2dch);
264
265 //pcurve on the cylinder
266 norCon.SetXYZ (deru.Crossed(derv).XYZ());
267
268 Pt.SetCoord(Or.X()+ConRad*Dx.X(),
269 Or.Y()+ConRad*Dx.Y(),
270 Or.Z()+ConRad*Dx.Z());
271 ElSLib::Parameters(Cyl,Pt ,u,v);
272 Standard_Real tol = Precision::PConfusion();
273 Standard_Boolean careaboutsens = 0;
c6541a0c 274 if(Abs(lu - fu - 2*M_PI) < tol) careaboutsens = 1;
7fd59977 275 if(u >= fu - tol && u < fu) u = fu;
276 if(u <= lu + tol && u > lu) u = lu;
c6541a0c 277 if(u < fu || u > lu) u = ChFiKPart_InPeriod(u,fu,fu + 2*M_PI,tol);
7fd59977 278
279 ElSLib::D1(u,v,Cyl,Pt,deru,derv);
280 gp_Dir norcyl = deru.Crossed(derv);
281 gp_Dir2d d2dCyl = gp::DX2d();
282 if( deru.Dot(Dy) < 0. ){
283 d2dCyl.Reverse();
284 if(careaboutsens && Abs(fu-u)<tol) u = lu;
285 }
286 else if(careaboutsens && Abs(lu-u)<tol) u = fu;
287 gp_Pnt2d p2dCyl(u,v);
288 gp_Lin2d lin2dCyl(p2dCyl,d2dCyl);
289 Handle(Geom2d_Line) GLin2dCyl = new Geom2d_Line(lin2dCyl);
290
291 //orientation
292 toreverse = ( norCon.Dot(norcyl) <= 0. );
293 if ((toreverse && plandab) || (!toreverse && !plandab) ) {
294 trans = TopAbs_REVERSED;
295 }
296 else {
297 trans = TopAbs_FORWARD;
298 }
299
300
301 if(plandab){
302 Data->ChangeInterferenceOnS2().
303 SetInterference(ChFiKPart_IndexCurveInDS(GCirCyl,DStr),
304 trans,GLin2dCyl,GLin2dCh2);
305 }
306 else{
307 Data->ChangeInterferenceOnS1().
308 SetInterference(ChFiKPart_IndexCurveInDS(GCirCyl,DStr),
309 trans,GLin2dCyl,GLin2dCh2);
310 }
311
312 return Standard_True;
313}
314
7fd59977 315//=======================================================================
316//function : MakeChamfer
81bba717 317//purpose : case cylinder/plane or plane/cylinder.
7fd59977 318//=======================================================================
319
320Standard_Boolean ChFiKPart_MakeChamfer(TopOpeBRepDS_DataStructure& DStr,
321 const Handle(ChFiDS_SurfData)& Data,
322 const gp_Pln& Pln,
323 const gp_Cylinder& Cyl,
324 const Standard_Real fu,
325 const Standard_Real lu,
326 const TopAbs_Orientation Or1,
327 const TopAbs_Orientation Or2,
328 const Standard_Real Dis1,
329 const Standard_Real Dis2,
330 const gp_Lin& Spine,
331 const Standard_Real First,
332 const TopAbs_Orientation Ofpl,
333 const Standard_Boolean plandab)
334{
81bba717 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
7fd59977 341
342 Standard_Real dis1=Dis1, dis2=Dis2;
343 if (!plandab){
344 dis1 = Dis2;
345 dis2 = Dis1;}
346
347 gp_Pnt OrSpine = ElCLib::Value(First,Spine);
348 gp_Pnt POnCyl, POnPln, OrCyl;
349
350 gp_Dir XDir = Spine.Direction();
351 gp_Ax3 AxPln = Pln.Position();
352 gp_Dir NorPln = AxPln.XDirection().Crossed(AxPln.YDirection());
353 gp_Dir NorF(NorPln);
354 if (Or1 == TopAbs_REVERSED)
355 {NorF.Reverse();}
356
357 gp_Ax3 AxCyl = Cyl.Position();
81bba717 358 // OrCyl is the point on axis of cylinder in the plane normal to the
359 // axis containing OrSpine
7fd59977 360 gp_Pnt Loc = AxCyl.Location();
361 gp_Vec LocSp(Loc, OrSpine);
362 gp_XYZ temp = AxCyl.Direction().XYZ();
363 temp = temp.Multiplied(LocSp.XYZ().Multiplied(temp) );
364 OrCyl.SetXYZ( (Loc.XYZ()).Added(temp) );
365// gp_XYZ temp = AxCyl.Direction().XYZ();
366// temp = temp.Multiplied( OrSpine.XYZ().Multiplied(temp) );
367// OrCyl.SetXYZ( (AxCyl.Location().XYZ()).Added(temp) );
368
369
81bba717 370 //construction of POnPln
7fd59977 371 gp_Vec VecTranslPln,tmp;
372
373 tmp = gp_Vec(OrSpine,OrCyl);
374 if ((Or2 == TopAbs_FORWARD && Cyl.Direct()) ||
375 (Or2 == TopAbs_REVERSED && !Cyl.Direct()))
376 {tmp.Reverse();}
377
378 VecTranslPln = gp_Vec( XDir.Crossed(NorPln) );
379 if( VecTranslPln.Dot(tmp) <= 0. )
380 {VecTranslPln.Reverse();}
381 VecTranslPln.Multiply(dis1);
382
383 POnPln.SetXYZ( (OrSpine.XYZ()).Added(VecTranslPln.XYZ()) );
384
81bba717 385 //construction of POnCyl
7fd59977 386 Standard_Real alpha = ( 2*ASin(dis2*0.5/Cyl.Radius()) );
387// gp_Vec VecTranslCyl;
388// VecTranslCyl = gp_Vec(OrSpine,OrCyl);
389
390// if ( ( XDir.Crossed(gp_Dir(VecTranslCyl)) ).Dot(NorF) <=0. )
391// {VecTranslCyl.Rotate(gp_Ax1(OrSpine,XDir),alpha);}
392// else
393// {VecTranslCyl.Rotate(gp_Ax1(OrSpine,XDir.Reversed()),alpha);}
394
395// POnCyl.SetXYZ( OrCyl.XYZ().Added(VecTranslCyl.XYZ()) );
396
397 gp_Vec VecCylTransl = gp_Vec(OrCyl,OrSpine);
398
399 if ( ( XDir.Crossed(gp_Dir(VecCylTransl)) ).Dot(NorF) > 0.) {
400 VecCylTransl.Rotate(gp_Ax1(OrCyl,XDir),alpha);
401 }
402 else {
403 VecCylTransl.Rotate(gp_Ax1(OrCyl,XDir.Reversed()),alpha);}
404
405 POnCyl.SetXYZ( OrCyl.XYZ().Added(VecCylTransl.XYZ()) );
406
81bba717 407 //construction of chamfer
7fd59977 408 Standard_Real UOnCyl,VOnCyl,UOnPln,VOnPln;
409 ElSLib::Parameters(Cyl,POnCyl,UOnCyl,VOnCyl);
410 POnCyl = ElSLib::CylinderValue(UOnCyl,VOnCyl,AxCyl,Cyl.Radius());
411 ElSLib::Parameters(Pln,POnPln,UOnPln,VOnPln);
412 POnPln = ElSLib::PlaneValue(UOnPln,VOnPln,AxPln);
413
81bba717 414 //construction of YDir to go to face1 from face2.
7fd59977 415 gp_Vec YDir(POnPln,POnCyl);
416 if (!plandab){
417 YDir.Reverse();
418 }
419 gp_Ax3 AxCh(POnPln,XDir.Crossed(YDir),XDir);
420
421 Handle(Geom_Plane) Chamfer = new Geom_Plane(AxCh);
422 Data->ChangeSurf(ChFiKPart_IndexSurfaceInDS(Chamfer,DStr));
423
81bba717 424 // FaceInterferences are loaded with pcurves and curves 3d.
425 //----------- edge plane-Chamfer
7fd59977 426 gp_Pnt2d PPln2d(UOnPln,VOnPln);
427 gp_Dir2d VPln2d(XDir.Dot(AxPln.XDirection()),
428 XDir.Dot(AxPln.YDirection()));
429 gp_Lin2d Lin2dPln(PPln2d,VPln2d);
430
431 POnPln = ElSLib::Value(UOnPln,VOnPln,Pln);
432 gp_Lin C3d(POnPln,XDir);
433
434 Standard_Real U,VOnChamfer;
435 ElSLib::PlaneParameters(AxCh,POnPln,U,VOnChamfer);
436 gp_Lin2d LOnChamfer(gp_Pnt2d(U,VOnChamfer),gp::DX2d());
437
438 Handle(Geom_Line) L3d = new Geom_Line (C3d);
439 Handle(Geom2d_Line) LFac = new Geom2d_Line(Lin2dPln);
440 Handle(Geom2d_Line) LFil = new Geom2d_Line(LOnChamfer);
441
442 gp_Dir NorFil=AxCh.Direction();
443 Standard_Boolean toreverse = ( NorFil.Dot(NorPln) <= 0. );
444
445 gp_Dir DirPlnCyl(gp_Vec(POnPln, POnCyl));
446 gp_Dir DirSPln(gp_Vec(OrSpine, POnPln));
447 Standard_Boolean PosChamfPln = DirPlnCyl.Dot(DirSPln) > 0;
448
449 if (PosChamfPln )
450 toreverse = !toreverse;
81bba717 451 // It is checked if the orientation of the Chamfer is the same as of the plane
7fd59977 452 if (toreverse)
453 {Data->ChangeOrientation() = TopAbs::Reverse(Ofpl);}
454 else
455 {Data->ChangeOrientation() = Ofpl;}
456
457 TopAbs_Orientation trans = TopAbs_FORWARD;
458 if ((!plandab && toreverse) || (plandab && !toreverse))
459 {trans=TopAbs_REVERSED;}
460
81bba717 461 //trans permits to determine the "material" side on S1(2) limited by L3d
7fd59977 462 if (plandab)
463 {Data->ChangeInterferenceOnS1().
464 SetInterference(ChFiKPart_IndexCurveInDS(L3d,DStr),trans,LFac,LFil);}
465 else
466 {Data->ChangeInterferenceOnS2().
467 SetInterference(ChFiKPart_IndexCurveInDS(L3d,DStr),trans,LFac,LFil);}
468
81bba717 469 //------------edge cylinder-Chamfer
7fd59977 470 gp_Pnt2d PCyl2d(UOnCyl,VOnCyl);
471 gp_Dir2d VCyl2d=gp::DY2d();
472 if ( XDir.Dot(AxCyl.Direction())<0 )
473 {VCyl2d.Reverse();}
474 gp_Lin2d Lin2dCyl(PCyl2d,VCyl2d);
475
476 POnCyl = ElSLib::Value(UOnCyl,VOnCyl,Cyl);
477 C3d = gp_Lin(POnCyl,XDir);
478
479 ElSLib::PlaneParameters(AxCh,POnCyl,U,VOnChamfer);
480 LOnChamfer = gp_Lin2d(gp_Pnt2d(U,VOnChamfer),gp::DX2d());
481
482 L3d = new Geom_Line (C3d);
483 LFac = new Geom2d_Line(Lin2dCyl);
484 LFil = new Geom2d_Line(LOnChamfer);
485
486 gp_Vec deru,derv;
487 ElSLib::CylinderD1(UOnCyl,VOnCyl,AxCyl,Cyl.Radius(),POnCyl,deru,derv);
488 gp_Dir NorCyl(deru.Crossed(derv));
489
490 toreverse = ( NorFil.Dot(NorCyl) <= 0. );
491
492 gp_Dir DirSCyl(gp_Vec(OrSpine, POnCyl));
493 Standard_Boolean PosChamfCyl = DirPlnCyl.Dot(DirSCyl) < 0;
494
495
496 if (PosChamfCyl)
497 toreverse = !toreverse;
498
499 trans = TopAbs_REVERSED;
500 if ((!plandab && toreverse) || (plandab && !toreverse))
501 {trans=TopAbs_FORWARD;}
502
503 if (plandab)
504 Data->ChangeInterferenceOnS2().
505 SetInterference(ChFiKPart_IndexCurveInDS(L3d,DStr),trans,LFac,LFil);
506 else
507 Data->ChangeInterferenceOnS1().
508 SetInterference(ChFiKPart_IndexCurveInDS(L3d,DStr),trans,LFac,LFil);
509 return Standard_True;
510}
511
512
513
514