Warnings on vc14 were eliminated
[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
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
7fd59977 17
42cf5bc1 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>
7fd59977 23#include <ElCLib.hxx>
24#include <ElSLib.hxx>
7fd59977 25#include <Geom2d_Circle.hxx>
42cf5bc1 26#include <Geom2d_Line.hxx>
7fd59977 27#include <Geom_Circle.hxx>
42cf5bc1 28#include <Geom_ConicalSurface.hxx>
29#include <Geom_CylindricalSurface.hxx>
30#include <Geom_Line.hxx>
7fd59977 31#include <Geom_Plane.hxx>
42cf5bc1 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>
7fd59977 44#include <IntAna_QuadQuadGeo.hxx>
42cf5bc1 45#include <Precision.hxx>
46#include <TopOpeBRepDS_DataStructure.hxx>
7fd59977 47
48//pour tester
7fd59977 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//=======================================================================
7fd59977 65Standard_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 ) {
0797d9d3 130#ifdef OCCT_DEBUG
81bba717 131 cout<<"the chamfer can't pass"<<endl;
63c629aa 132#endif
7fd59977 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;
c6541a0c 266 if(Abs(lu - fu - 2*M_PI) < tol) careaboutsens = 1;
7fd59977 267 if(u >= fu - tol && u < fu) u = fu;
268 if(u <= lu + tol && u > lu) u = lu;
c6541a0c 269 if(u < fu || u > lu) u = ChFiKPart_InPeriod(u,fu,fu + 2*M_PI,tol);
7fd59977 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
7fd59977 307//=======================================================================
308//function : MakeChamfer
81bba717 309//purpose : case cylinder/plane or plane/cylinder.
7fd59977 310//=======================================================================
311
312Standard_Boolean ChFiKPart_MakeChamfer(TopOpeBRepDS_DataStructure& DStr,
313 const Handle(ChFiDS_SurfData)& Data,
314 const gp_Pln& Pln,
315 const gp_Cylinder& Cyl,
35e08fe8 316 const Standard_Real /*fu*/,
317 const Standard_Real /*lu*/,
7fd59977 318 const TopAbs_Orientation Or1,
319 const TopAbs_Orientation Or2,
6552f078 320 const Standard_Real dis1,
321 const Standard_Real dis2,
7fd59977 322 const gp_Lin& Spine,
323 const Standard_Real First,
324 const TopAbs_Orientation Ofpl,
325 const Standard_Boolean plandab)
326{
81bba717 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
7fd59977 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();
81bba717 344 // OrCyl is the point on axis of cylinder in the plane normal to the
345 // axis containing OrSpine
12945d77 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 );
7fd59977 351
81bba717 352 //construction of POnPln
7fd59977 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
81bba717 367 //construction of POnCyl
7fd59977 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
81bba717 389 //construction of chamfer
7fd59977 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
81bba717 396 //construction of YDir to go to face1 from face2.
7fd59977 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
81bba717 406 // FaceInterferences are loaded with pcurves and curves 3d.
407 //----------- edge plane-Chamfer
7fd59977 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;
81bba717 433 // It is checked if the orientation of the Chamfer is the same as of the plane
7fd59977 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
81bba717 443 //trans permits to determine the "material" side on S1(2) limited by L3d
7fd59977 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
81bba717 451 //------------edge cylinder-Chamfer
7fd59977 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