0024624: Lost word in license statement in source files
[occt.git] / src / ChFiKPart / ChFiKPart_ComputeData_ChAsymPlnCon.cxx
CommitLineData
b311480e 1// Created on: 1998-06-18
2// Created by: Philippe NOUAILLE
3// Copyright (c) 1998-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
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
61Standard_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 DEB
81bba717 137 cout<<"the chamfer can't pass"<<endl;
7fd59977 138#endif
139 return Standard_False;
140 }
c6541a0c 141 SemiAngl = M_PI / 2. - Angle;
7fd59977 142 }
143 else {
144 ChamfRad = Spine.Radius() + Dis;
c6541a0c 145 SemiAngl = Angle - M_PI / 2.;
7fd59977 146 }
147
148 if (ouvert) {
149 if (Abs(angCon) - Abs(SemiAngl) > -Precision::Confusion() ) {
81bba717 150 cout<<"wrong choice of angle for the chamfer"<<endl;
7fd59977 151 return Standard_False;
152 }
153 }
154 }
155 else {
156 Standard_Real Dis1;
157 move = Dis * Cos(angCon);
158 if (ouvert) {
159 SemiAngl = Abs(angCon) + Angle;
160
c6541a0c 161 if ( (M_PI / 2. - SemiAngl) < Precision::Confusion() ) {
81bba717 162 cout <<"wrong choice of angle for the chamfer"<<endl;
7fd59977 163 return Standard_False;
164 }
165 Dis1 = move * Tan(SemiAngl) - Dis * Abs(Sin(angCon));
166
167 if (!dedans) SemiAngl = -SemiAngl;
168
169 }
170 else {
171 SemiAngl = Abs(angCon) - Angle;
172
173 if ( Abs(SemiAngl) < Precision::Confusion() ) {
174 iscylinder = Standard_True;
175 Dis1 = Dis * Abs(Sin(angCon));
176 }
177 else {
178 Dis1 = Dis * Abs(Sin(angCon)) - move * Tan(SemiAngl);
179 }
180
181 if (SemiAngl > Precision::Confusion())
182 isConPar = Standard_True;
183
184 if (dedans) SemiAngl = -SemiAngl;
185
186 }
187
188 // compute the parameters of the conical chamfer
189 if (dedans) {
190 ChamfRad = Spine.Radius() - Dis1;
191
192 if ( Abs(ChamfRad) < Precision::Confusion() ) pointu = Standard_True;
193 if( ChamfRad < 0 ) {
194#ifdef DEB
81bba717 195 cout<<"the chamfer can't pass"<<endl;
7fd59977 196#endif
197 return Standard_False;
198 }
199 }
200 else {
201 ChamfRad = Spine.Radius() + Dis1;
202 //Dpl.Reverse();
203 }
204
205 if (ouvert)
206 dis = Dis1 + Dis * Abs(Sin(angCon));
207 else
208 dis = Dis1 - Dis * Abs(Sin(angCon));
209 }
210
211 Or.SetCoord( Or.X()+ move*Dpl.X(),
212 Or.Y()+ move*Dpl.Y(),
213 Or.Z()+ move*Dpl.Z());
214 gp_Pnt Pt(Or.X()+dis*PosPl.XDirection().X(),
215 Or.Y()+dis*PosPl.XDirection().Y(),
216 Or.Z()+dis*PosPl.XDirection().Z());
217
218 gp_Ax3 ChamfAx3(PtPl,Dpl,Dx);
219
220
221 if (iscylinder) {
222 Handle (Geom_CylindricalSurface)
223 gcyl = new Geom_CylindricalSurface( ChamfAx3, ChamfRad );
224
225 // changes due to the fact the parameters of the chamfer must go increasing
226 // from surface S1 to surface S2
227 if (!plandab) {
228 gcyl->VReverse();// be carefull : the SemiAngle was changed
229 ChamfAx3 = gcyl->Position();
230 }
231
232 // changes due to the fact we have reversed the V direction of
233 // parametrization
234 if (ChamfAx3.YDirection().Dot(DSp) <= 0.) {
235 ChamfAx3.YReverse();
236 gcyl->SetPosition(ChamfAx3);
237 }
238
239 Data->ChangeSurf(ChFiKPart_IndexSurfaceInDS(gcyl,DStr));
240
241 Standard_Boolean torevcha = !ChamfAx3.Direct();
242 gp_Dir cylaxe = (ChamfAx3.Axis()).Direction();
243 torevcha = ( (torevcha && !plandab) || (!torevcha && plandab));
244
245 if (torevcha) cylaxe.Reverse();
246 Standard_Boolean toreverse = (norf.Dot(cylaxe) < 0.);
247
248 if ((toreverse && dedans) || (!toreverse && !dedans))
249 Data->ChangeOrientation() = TopAbs_REVERSED;
250 else
251 Data->ChangeOrientation() = TopAbs_FORWARD;
252
253 //we load the faceInterference with the pcurves and
254 // the 3d curves
255
256 // Case of the plane face
257 // NB: in the case 'pointu', no pcurve on the plane surface
258 // and no intersection plane-chamfer are needed
259
260 // intersection plane-chamfer
261 Handle(Geom_Circle) GCirPln;
262 Handle(Geom2d_Circle) GCir2dPln;
263 gp_Ax2 CirAx2 = ChamfAx3.Ax2();
264 CirAx2.SetLocation(PtPl);
265
266 Pt.SetCoord(PtPl.X()+ChamfRad*Dx.X(),
267 PtPl.Y()+ChamfRad*Dx.Y(),
268 PtPl.Z()+ChamfRad*Dx.Z());
269 gp_Circ CirPln(CirAx2,ChamfRad);
270 GCirPln = new Geom_Circle(CirPln);
271
272 //pcurve on the plane
273 ElSLib::PlaneParameters(PosPl,Pt ,u,v);
274 gp_Pnt2d p2dPln(u,v);
275 gp_Dir2d d2d(DSp.Dot(PosPl.XDirection()),DSp.Dot(PosPl.YDirection()));
276 gp_Ax22d ax2dPln(pt2dPln, gp_Dir2d(gp_Vec2d(pt2dPln,p2dPln)),d2d);
277 gp_Circ2d cir2dPln(ax2dPln,ChamfRad);
278 GCir2dPln = new Geom2d_Circle(cir2dPln);
279
280 //pcurve on chamfer
281 gp_Pnt2d p2dch;
282 p2dch.SetCoord(0.,0.);
283 // ElSLib::CylinderD1(0.,0.,ChamfAx3,ChamfRad,Pt,deru,derv);
284 gp_Lin2d lin2dch(p2dch,gp::DX2d());
285 Handle(Geom2d_Line) GLin2dCh1 = new Geom2d_Line(lin2dch);
286
287 //orientation
288 TopAbs_Orientation trans;
289 gp_Dir norpl = PosPl.XDirection().Crossed(PosPl.YDirection());
290 toreverse = (norpl.Dot(cylaxe) < 0.);
291
292 toreverse = (toreverse && plandab) || (!toreverse && !plandab);
293
294 if ((toreverse && dedans) || (!toreverse && !dedans)) {
295 trans = TopAbs_FORWARD;
296 }
297 else {
298 trans = TopAbs_REVERSED;
299 }
300
301 if (plandab) {
302 Data->ChangeInterferenceOnS1().
303 SetInterference(ChFiKPart_IndexCurveInDS(GCirPln,DStr),
304 trans,GCir2dPln,GLin2dCh1);
305 }
306 else {
307 Data->ChangeInterferenceOnS2().
308 SetInterference(ChFiKPart_IndexCurveInDS(GCirPln,DStr),
309 trans,GCir2dPln,GLin2dCh1);
310 }
311
312 // Case of the conical face
313
314 //intersection cone-chamfer
315 Standard_Real Rad;
316 if (dedans)
317 Rad = ChamfRad + dis;
318 else
319 Rad = ChamfRad - dis;
320
321 CirAx2.SetLocation(Or);
322 gp_Circ CirCon(CirAx2, Rad);
323 Handle(Geom_Circle) GCirCon = new Geom_Circle(CirCon);
324
325 //pcurve on chamfer
326 if (plandab)
327 v = sqrt(dis*dis + move*move);
328 else
329 v = - sqrt(dis*dis + move*move);
330 p2dch.SetCoord(0.,v);
331 ElSLib::CylinderD1(0.,v,ChamfAx3,ChamfRad,Pt,deru,derv);
332 lin2dch.SetLocation(p2dch);
333 Handle(Geom2d_Line) GLin2dCh2 = new Geom2d_Line(lin2dch);
334
335 //pcurve on cone
336 Pt.SetCoord(Or.X()+Rad*Dx.X(),
337 Or.Y()+Rad*Dx.Y(),
338 Or.Z()+Rad*Dx.Z());
339 ElSLib::Parameters(Con,Pt ,u,v);
340 Standard_Real tol = Precision::PConfusion();
c6541a0c 341 if(u >= 2*M_PI - tol && u <= 2*M_PI) u = 0.;
7fd59977 342 if(u >= fu - tol && u < fu) u = fu;
343 if(u <= lu + tol && u > lu) u = lu;
c6541a0c 344 if(u < fu || u > lu) u = ElCLib::InPeriod(u,fu,fu + 2*M_PI);
7fd59977 345 ElSLib::D1(u,v,Con,Pt,deru,derv);
346 gp_Pnt2d p2dCon(u,v);
347 gp_Dir2d d2dCon;
348 if ( deru.Dot(DSp)<=0. )
349 d2dCon = - gp::DX2d();
350 else
351 d2dCon = gp::DX2d();
352 gp_Lin2d lin2dCon(p2dCon,d2dCon);
353 Handle(Geom2d_Line) GLin2dCon = new Geom2d_Line(lin2dCon);
354
355 //orientation
356 gp_Dir norcon = deru.Crossed(derv);
357
358 gp_Dir DirCon = (Con.Axis()).Direction();
359 if (angCon > Precision::Confusion()) DirCon.Reverse();
360 Standard_Boolean torevcon = ( norcon.Dot(DirCon) < 0. );
361
362 if ((torevcon && dedans) || (!torevcon && !dedans) ) {
363 trans = TopAbs_REVERSED;
364 }
365 else {
366 trans = TopAbs_FORWARD;
367 }
368
369 if(plandab){
370 Data->ChangeInterferenceOnS2().
371 SetInterference(ChFiKPart_IndexCurveInDS(GCirCon,DStr),
372 trans,GLin2dCon,GLin2dCh2);
373 }
374 else {
375 Data->ChangeInterferenceOnS1().
376 SetInterference(ChFiKPart_IndexCurveInDS(GCirCon,DStr),
377 trans,GLin2dCon,GLin2dCh2);
378 }
379 }
380 else {
381 Handle (Geom_ConicalSurface)
382 gcon = new Geom_ConicalSurface( ChamfAx3, SemiAngl, ChamfRad );
383
384 // changes due to the fact the parameters of the chamfer must go increasing
385 // from surface S1 to surface S2
386 if (!plandab) {
387 gcon->VReverse();// be carefull : the SemiAngle was changed
388 ChamfAx3 = gcon->Position();
389 SemiAngl = gcon->SemiAngle();
390 }
391
392 // changes due to the fact we have reversed the V direction of
393 // parametrization
394 if (ChamfAx3.YDirection().Dot(DSp) <= 0.) {
395 ChamfAx3.YReverse();
396 gcon->SetPosition(ChamfAx3);
397 }
398
399 Data->ChangeSurf(ChFiKPart_IndexSurfaceInDS(gcon,DStr));
400
401 //compute the chamfer's orientation according to the orientation
402 // of the faces
403
404 //search the normal to the conical chamfer
405 gp_Pnt P;
406 u = 0.;
407 if (plandab)
408 v = sqrt(dis*dis + move*move);
409 else
410 v = - sqrt(dis*dis + move*move);
411
412 ElSLib::ConeD1(u,v,ChamfAx3,ChamfRad,SemiAngl,P,deru,derv);
413 gp_Dir norchamf(deru.Crossed(derv));
414
415 Standard_Boolean toreverse = (norf.Dot(norchamf) < 0.);
416
417 if (isConPar) toreverse = !toreverse;
418
419 if (toreverse)
420 Data->ChangeOrientation() = TopAbs_REVERSED;
421 else
422 Data->ChangeOrientation() = TopAbs_FORWARD;
423
424 //we load the faceInterference with the pcurves and
425 // the 3d curves
426
427 // Case of the plane face
428 // NB: in the case 'pointu', no pcurve on the plane surface
429 // and no intersection plane-chamfer are needed
430
431 // intersection plane-chamfer
432 Handle(Geom_Circle) GCirPln;
433 Handle(Geom2d_Circle) GCir2dPln;
434 gp_Ax2 CirAx2 = ChamfAx3.Ax2();
435 CirAx2.SetLocation(PtPl);
436
437 if (!pointu) {
438 Pt.SetCoord(PtPl.X()+ChamfRad*Dx.X(),
439 PtPl.Y()+ChamfRad*Dx.Y(),
440 PtPl.Z()+ChamfRad*Dx.Z());
441 gp_Circ CirPln(CirAx2,ChamfRad);
442 GCirPln = new Geom_Circle(CirPln);
443
444 //pcurve on the plane
445 ElSLib::PlaneParameters(PosPl,Pt ,u,v);
446 gp_Pnt2d p2dPln(u,v);
447 gp_Dir2d d2d(DSp.Dot(PosPl.XDirection()),DSp.Dot(PosPl.YDirection()));
448 gp_Ax22d ax2dPln(pt2dPln, gp_Dir2d(gp_Vec2d(pt2dPln,p2dPln)),d2d);
449 gp_Circ2d cir2dPln(ax2dPln,ChamfRad);
450 GCir2dPln = new Geom2d_Circle(cir2dPln);
451 }
452
453 //pcurve on chamfer
454 gp_Pnt2d p2dch;
455 p2dch.SetCoord(0.,0.);
456 ElSLib::ConeD1(0.,0.,ChamfAx3,ChamfRad,SemiAngl,Pt,deru,derv);
457 gp_Lin2d lin2dch(p2dch,gp::DX2d());
458 Handle(Geom2d_Line) GLin2dCh1 = new Geom2d_Line(lin2dch);
459
460 //orientation
461 TopAbs_Orientation trans;
462 gp_Dir norpl = PosPl.XDirection().Crossed(PosPl.YDirection());
463 if (!pointu)
464 norchamf.SetXYZ (deru.Crossed(derv).XYZ());
465 toreverse = ( norchamf.Dot(norpl) <= 0. );
466
467 if (isConPar) toreverse = !toreverse;
468
469 if ((toreverse && plandab) || (!toreverse && !plandab)){
470 trans = TopAbs_FORWARD;
471 }
472 else {
473 trans = TopAbs_REVERSED;
474 }
475
476 if (plandab) {
477 Data->ChangeInterferenceOnS1().
478 SetInterference(ChFiKPart_IndexCurveInDS(GCirPln,DStr),
479 trans,GCir2dPln,GLin2dCh1);
480 }
481 else {
482 Data->ChangeInterferenceOnS2().
483 SetInterference(ChFiKPart_IndexCurveInDS(GCirPln,DStr),
484 trans,GCir2dPln,GLin2dCh1);
485 }
486
487 // Case of the conical face
488
489 //intersection cone-chamfer
490 Standard_Real Rad;
491 if (dedans)
492 Rad = ChamfRad + dis;
493 else
494 Rad = ChamfRad - dis;
495
496 CirAx2.SetLocation(Or);
497 gp_Circ CirCon(CirAx2, Rad);
498 Handle(Geom_Circle) GCirCon = new Geom_Circle(CirCon);
499
500 //pcurve on chamfer
501 if (plandab)
502 v = sqrt(dis*dis + move*move);
503 else
504 v = - sqrt(dis*dis + move*move);
505 p2dch.SetCoord(0.,v);
506 ElSLib::ConeD1(0.,v,ChamfAx3,ChamfRad,SemiAngl,Pt,deru,derv);
507 lin2dch.SetLocation(p2dch);
508 Handle(Geom2d_Line) GLin2dCh2 = new Geom2d_Line(lin2dch);
509
510 //pcurve on cone
511 norchamf.SetXYZ (deru.Crossed(derv).XYZ());
512
513 Pt.SetCoord(Or.X()+Rad*Dx.X(),
514 Or.Y()+Rad*Dx.Y(),
515 Or.Z()+Rad*Dx.Z());
516 ElSLib::Parameters(Con,Pt ,u,v);
517 Standard_Real tol = Precision::PConfusion();
c6541a0c 518 if (u >= 2*M_PI - tol && u <= 2*M_PI) u = 0.;
7fd59977 519 if (u >= fu - tol && u < fu) u = fu;
520 if (u <= lu + tol && u > lu) u = lu;
c6541a0c 521 if (u < fu || u > lu) u = ElCLib::InPeriod(u,fu,fu + 2*M_PI);
7fd59977 522 ElSLib::D1(u,v,Con,Pt,deru,derv);
523 gp_Pnt2d p2dCon(u,v);
524 gp_Dir2d d2dCon;
525 if ( deru.Dot(DSp)<=0. )
526 d2dCon = - gp::DX2d();
527 else
528 d2dCon = gp::DX2d();
529 gp_Lin2d lin2dCon(p2dCon,d2dCon);
530 Handle(Geom2d_Line) GLin2dCon = new Geom2d_Line(lin2dCon);
531
532 //orientation
533 gp_Dir norcon = deru.Crossed(derv);
534
535 gp_Dir DirCon = (Con.Axis()).Direction();
536 gp_Dir DirChamf = (gcon->Axis()).Direction();
537 if (angCon > Precision::Confusion()) DirCon.Reverse();
538 if (SemiAngl > Precision::Confusion()) DirChamf.Reverse();
539
540 Standard_Boolean torevcon = ( norcon.Dot(DirCon) > 0. );
541 Standard_Boolean torevcha = ( norchamf.Dot(DirChamf) > 0. );
542
543 toreverse = ( (torevcon && !torevcha) || (!torevcon && torevcha) );
544
545 if ((toreverse && plandab) || (!toreverse && !plandab) ) {
546 trans = TopAbs_REVERSED;
547 }
548 else {
549 trans = TopAbs_FORWARD;
550 }
551
552 if(plandab){
553 Data->ChangeInterferenceOnS2().
554 SetInterference(ChFiKPart_IndexCurveInDS(GCirCon,DStr),
555 trans,GLin2dCon,GLin2dCh2);
556 }
557 else {
558 Data->ChangeInterferenceOnS1().
559 SetInterference(ChFiKPart_IndexCurveInDS(GCirCon,DStr),
560 trans,GLin2dCon,GLin2dCh2);
561 }
562
563 }
564 return Standard_True;
565}
566
567
568
569