0025418: Debug output to be limited to OCC development environment
[occt.git] / src / ChFiKPart / ChFiKPart_ComputeData_FilPlnCyl.cxx
CommitLineData
b311480e 1// Created on: 1994-02-03
2// Created by: Isabelle GRIGNON
3// Copyright (c) 1994-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.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
81bba717 50//purpose : case cylinder/plane or plane/cylinder.
7fd59977 51//=======================================================================
52
53Standard_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{
81bba717 67 //calculate the cylinder fillet.
7fd59977 68
81bba717 69 //plane deviated from radius
7fd59977 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
81bba717 78 // Parallel cylinder
7fd59977 79 Standard_Real ROff = Cyl.Radius();
7fd59977 80
81 if ((Or2 == TopAbs_FORWARD && Cyl.Direct()) ||
82 (Or2 == TopAbs_REVERSED && !Cyl.Direct()))
83 ROff+=Radius;
84 else if (Radius < ROff) {
96a95605 85 ROff-=Radius;
7fd59977 86 }
87 else {
0797d9d3 88#ifdef OCCT_DEBUG
81bba717 89 cout<<"the fillet does not pass"<<endl;
7fd59977 90#endif
91 return Standard_False;
92 }
81bba717 93 // intersection of the parallel plane and of the parallel cylinder.
7fd59977 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
81bba717 116 // Construction fillet
7fd59977 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)
c6541a0c 123 UOnCyl = ElCLib::InPeriod(UOnCyl,fu,fu+2*M_PI);
7fd59977 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);
81bba717 136 // construction YDir to go from face1 to face2.
7fd59977 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
81bba717 144 // FaceInterferences are loaded with pcurves and curves 3D.
145 // edge plane-Fillet
7fd59977 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);
c6541a0c 154 if(UOnFillet > M_PI) UOnFillet = 0.;
7fd59977 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. );
81bba717 164 // It is checked if the orientation of the cylinder is the same as of the plane.
7fd59977 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
81bba717 184 // edge cylinder-Fillet.
7fd59977 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);
c6541a0c 192 if(UOnFillet > M_PI) UOnFillet = 0.;
7fd59977 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
81bba717 223//purpose : case cylinder/plane or plane/cylinder.
7fd59977 224//=======================================================================
225
226Standard_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
81bba717 241//calculation of the fillet (torus or sphere).
7fd59977 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;
81bba717 261 // Modification for the PtSp found at the wrong side of the sewing edge.
7fd59977 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);
c6541a0c 267 if ((Abs(u)<acote) || (Abs(u-(2*M_PI))<acote)){
7fd59977 268 ElCLib::D1(First+0.2,Spine,PtSp2,DSp2);
269 Standard_Real u2,v2;
270 ElSLib::Parameters(Cyl,PtSp2,u2,v2);
c6541a0c
D
271 if (Abs(u2-u)>M_PI){
272 u = (2*M_PI)-u;
7fd59977 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 }
81bba717 279 // end of modif
7fd59977 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){
0797d9d3 296#ifdef OCCT_DEBUG
81bba717 297 cout<<"the fillet can't pass"<<endl;
7fd59977 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
81bba717 320 // It is checked if the orientation of the fillet is the same as of faces.
7fd59977 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)){
c6541a0c
D
328 if (c1sphere) { v = - M_PI / 2; }
329 else { v = 3 * M_PI / 2; }
7fd59977 330 }
c6541a0c 331 else { v = M_PI / 2; }
7fd59977 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
81bba717 347 // FaceInterferences are loaded with pcurves and curves 3d.
7fd59977 348
81bba717 349 // The plane face.
7fd59977 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
81bba717 395 // The cylindrical face.
7fd59977 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) {
c6541a0c 401 if (plandab && !c1sphere) { v = 2 * M_PI; }
7fd59977 402 else { v = 0. ; }
403 }
c6541a0c 404 else { v = M_PI; }
7fd59977 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;
c6541a0c 418 if(Abs(lu - fu - 2*M_PI) < tol) careaboutsens = 1;
7fd59977 419 if(u >= fu - tol && u < fu) u = fu;
420 if(u <= lu + tol && u > lu) u = lu;
c6541a0c 421 if(u < fu || u > lu) u = ChFiKPart_InPeriod(u,fu,fu + 2*M_PI,tol);
7fd59977 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