0024023: Revamp the OCCT Handle -- ambiguity
[occt.git] / src / ChFiKPart / ChFiKPart_ComputeData_FilPlnCon.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_Cone.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
43#include <IntAna_QuadQuadGeo.hxx>
44
45#include <ChFiKPart_ComputeData_Fcts.hxx>
46
47//=======================================================================
48//function : MakeFillet
81bba717 49//purpose : case cone/plane or plane/cone.
7fd59977 50//=======================================================================
51
52Standard_Boolean ChFiKPart_MakeFillet(TopOpeBRepDS_DataStructure& DStr,
53 const Handle(ChFiDS_SurfData)& Data,
54 const gp_Pln& Pln,
55 const gp_Cone& Con,
56 const Standard_Real fu,
57 const Standard_Real lu,
58 const TopAbs_Orientation Or1,
59 const TopAbs_Orientation Or2,
60 const Standard_Real Radius,
61 const gp_Circ& Spine,
62 const Standard_Real First,
63 const TopAbs_Orientation Ofpl,
64 const Standard_Boolean plandab)
65{
81bba717 66//calculate the fillet (torus or sphere).
7fd59977 67 Standard_Boolean c1sphere = Standard_False;
68 gp_Ax3 PosPl = Pln.Position();
69 gp_Dir Dpnat = PosPl.XDirection().Crossed(PosPl.YDirection());
70 gp_Dir Dp = Dpnat;
71 gp_Dir Df = Dp;
72 if (Or1 == TopAbs_REVERSED) { Dp.Reverse(); }
73 if (Ofpl == TopAbs_REVERSED) { Df.Reverse(); }
74
75 gp_Pnt Or = Con.Location();
76 Standard_Real u,v;
77 ElSLib::PlaneParameters(PosPl,Or,u,v);
78 gp_Pnt2d c2dPln(u,v);
79 ElSLib::PlaneD0(u,v,PosPl,Or);
80 gp_Pnt cPln = Or;
81 Or.SetCoord(Or.X()+Radius*Dp.X(),
82 Or.Y()+Radius*Dp.Y(),
83 Or.Z()+Radius*Dp.Z());
84
85 gp_Pnt PtSp;
86 gp_Vec DSp;
87 ElCLib::D1(First,Spine,PtSp,DSp);
88 IntAna_QuadQuadGeo CInt (Pln,Con,Precision::Angular(),
89 Precision::Confusion());
90 gp_Pnt Pv;
91 if (CInt.IsDone()) {
81bba717 92 //The origin of the fillet is set at the start point on the
93 //guideline.
7fd59977 94 Pv = ElCLib::Value(ElCLib::Parameter(CInt.Circle(1),PtSp),
95 CInt.Circle(1));
96 }
97 else { return Standard_False; }
98 gp_Dir Dx(gp_Vec(cPln,Pv));
99 gp_Dir Dy(DSp);
100 ElSLib::Parameters(Con,Pv,u,v);
101 gp_Pnt PtCon;
102 gp_Vec Vu,Vv;
103 ElSLib::D1(u,v,Con,PtCon,Vu,Vv);
104 gp_Dir Dc(Vu.Crossed(Vv));
105 if (Or2 == TopAbs_REVERSED) { Dc.Reverse(); }
106 gp_Dir Dz = Dp;
107
108 gp_Pnt pp(Pv.X()+Dc.X(),Pv.Y()+Dc.Y(),Pv.Z()+Dc.Z());
109 ElSLib::PlaneParameters(PosPl,pp,u,v);
110 ElSLib::PlaneD0(u,v,PosPl,pp);
111 gp_Dir ddp(gp_Vec(Pv,pp));
112 ElSLib::Parameters(Con,Pv,u,v);
113 gp_Vec dcu,dcv;
114 ElSLib::D1(u,v,Con,pp,dcu,dcv);
115 gp_Dir ddc(dcv);
116 if(ddc.Dot(Dp) < 0.) ddc.Reverse();
117 Standard_Real Ang = ddp.Angle(ddc);
118 Standard_Real Rabio = Radius/Tan(Ang/2);
119 Standard_Real Maxrad = cPln.Distance(Pv);
120 Standard_Real Rad;
121 Standard_Boolean dedans = Dx.Dot(Dc) <= 0. ;
122 if( dedans ){
123 if (!plandab){ Dz.Reverse(); }
124 Rad = Maxrad - Rabio;
125 if(Abs(Rad) <= Precision::Confusion()){ c1sphere = Standard_True; }
126 else if(Rad < 0){
0797d9d3 127#ifdef OCCT_DEBUG
81bba717 128 cout<<"the fillet does not pass"<<endl;
63c629aa 129#endif
7fd59977 130 return Standard_False;
131 }
132 }
133 else {
134 if (plandab){ Dz.Reverse(); }
135 Rad = Maxrad + Rabio;
136 }
137 gp_Ax3 FilAx3(Or,Dz,Dx);
138 if (FilAx3.YDirection().Dot(Dy) <= 0.){ FilAx3.YReverse(); }
139
140 if(c1sphere) {
141 Handle(Geom_SphericalSurface)
142 gsph = new Geom_SphericalSurface(FilAx3,Radius);
143 Data->ChangeSurf(ChFiKPart_IndexSurfaceInDS(gsph,DStr));
144 }
145 else{
146 Handle(Geom_ToroidalSurface)
147 gtor = new Geom_ToroidalSurface(FilAx3,Rad,Radius);
148 Data->ChangeSurf(ChFiKPart_IndexSurfaceInDS(gtor,DStr));
149 }
150
81bba717 151 // It is checked if the orientation of the fillet is the same
152 // as of the faces.
7fd59977 153 gp_Pnt P,PP;
154 gp_Vec deru,derv;
155 P.SetCoord(cPln.X()+Rad*Dx.X(),
156 cPln.Y()+Rad*Dx.Y(),
157 cPln.Z()+Rad*Dx.Z());
158 if(c1sphere){
159 ElSLib::SphereParameters(FilAx3,Rad,P,u,v);
160 ElSLib::SphereD1(u,v,FilAx3,Rad,PP,deru,derv);
161 }
162 else{
163 ElSLib::TorusParameters(FilAx3,Rad,Radius,P,u,v);
164 ElSLib::TorusD1(u,v,FilAx3,Rad,Radius,PP,deru,derv);
c6541a0c 165 if(!plandab && Ang < M_PI/2 && dedans) v = v + 2*M_PI;
7fd59977 166 }
167 gp_Pnt2d p2dFil(0.,v);
168 gp_Dir norFil(deru.Crossed(derv));
169 Standard_Boolean toreverse = ( norFil.Dot(Df) <= 0. );
170 if (toreverse) { Data->ChangeOrientation() = TopAbs_REVERSED; }
171 else { Data->ChangeOrientation() = TopAbs_FORWARD; }
172
81bba717 173 // FaceInterferences are loaded with pcurves and curves 3d.
7fd59977 174 // ---------------------------------------------------------------
175
81bba717 176 // The plane face.
7fd59977 177 // --------------
178
179 Handle(Geom2d_Circle) GCirc2dPln;
180 Handle(Geom_Circle) GCircPln;
181 gp_Ax2 circAx2 = FilAx3.Ax2();
182 if(!c1sphere){
183 ElSLib::PlaneParameters(PosPl,P,u,v);
184 gp_Pnt2d p2dPln(u,v);
185 gp_Dir2d d2d(DSp.Dot(PosPl.XDirection()),DSp.Dot(PosPl.YDirection()));
186 gp_Ax22d ax2dPln(c2dPln,gp_Dir2d(gp_Vec2d(c2dPln,p2dPln)),d2d);
187 gp_Circ2d circ2dPln(ax2dPln,Rad);
188 GCirc2dPln = new Geom2d_Circle(circ2dPln);
189 circAx2.SetLocation(cPln);
190 gp_Circ circPln(circAx2,Rad);
191 GCircPln = new Geom_Circle(circPln);
192 }
193 gp_Lin2d lin2dFil(p2dFil,gp::DX2d());
194 Handle(Geom2d_Line) GLin2dFil1 = new Geom2d_Line(lin2dFil);
195 toreverse = ( norFil.Dot(Dpnat) <= 0. );
196 TopAbs_Orientation trans;
197 if ((toreverse && plandab) || (!toreverse && !plandab) ){
198 trans = TopAbs_FORWARD;
199 }
200 else {
201 trans = TopAbs_REVERSED;
202 }
203 if(plandab){
204 Data->ChangeInterferenceOnS1().
205 SetInterference(ChFiKPart_IndexCurveInDS(GCircPln,DStr),
206 trans,GCirc2dPln,GLin2dFil1);
207 }
208 else{
209 Data->ChangeInterferenceOnS2().
210 SetInterference(ChFiKPart_IndexCurveInDS(GCircPln,DStr),
211 trans,GCirc2dPln,GLin2dFil1);
212 }
213
81bba717 214 // The conic face.
7fd59977 215 // ----------------
216
217 P.SetCoord(Pv.X()+Rabio*ddc.X(),
218 Pv.Y()+Rabio*ddc.Y(),
219 Pv.Z()+Rabio*ddc.Z());
220 if(c1sphere){
221 ElSLib::SphereParameters(FilAx3,Radius,P,u,v);
222 ElSLib::SphereD1(u,v,FilAx3,Radius,PP,deru,derv);
223 }
224 else{
225 ElSLib::TorusParameters(FilAx3,Rad,Radius,P,u,v);
226 ElSLib::TorusD1(u,v,FilAx3,Rad,Radius,PP,deru,derv);
c6541a0c 227 if(plandab && Ang < M_PI/2 && dedans) v = v + 2*M_PI;
7fd59977 228 }
229 norFil = deru.Crossed(derv);
230 p2dFil.SetCoord(0.,v);
231 lin2dFil.SetLocation(p2dFil);
232 Handle(Geom2d_Line) GLin2dFil2 = new Geom2d_Line(lin2dFil);
233 ElSLib::Parameters(Con,P,u,v);
234 Standard_Real tol = Precision::PConfusion();
235 Standard_Boolean careaboutsens = 0;
c6541a0c 236 if(Abs(lu - fu - 2*M_PI) < tol) careaboutsens = 1;
7fd59977 237 if(u >= fu - tol && u < fu) u = fu;
238 if(u <= lu + tol && u > lu) u = lu;
c6541a0c 239 if(u < fu || u > lu) u = ElCLib::InPeriod(u,fu,fu + 2*M_PI);
7fd59977 240 ElSLib::D1(u,v,Con,PP,deru,derv);
241 gp_Dir norCon = deru.Crossed(derv);
242 gp_Dir2d d2dCon = gp::DX2d();
243 if( deru.Dot(Dy) < 0. ){
244 d2dCon.Reverse();
245 if(careaboutsens && Abs(fu-u)<tol) u = lu;
246 }
247 else if(careaboutsens && Abs(lu-u)<tol) u = fu;
248 gp_Pnt2d p2dCon(u,v);
249 gp_Lin2d lin2dCon(p2dCon,d2dCon);
250 Handle(Geom2d_Line) GLin2dCon = new Geom2d_Line(lin2dCon);
251 Standard_Real scal = gp_Vec(Dp).Dot(gp_Vec(Pv,P));
252 PP.SetCoord(cPln.X()+scal*Dp.X(),
253 cPln.Y()+scal*Dp.Y(),
254 cPln.Z()+scal*Dp.Z());
255 circAx2.SetLocation(PP);
256 gp_Circ circCon(circAx2,P.Distance(PP));
257 Handle(Geom_Circle) GCircCon = new Geom_Circle(circCon);
258 toreverse = ( norFil.Dot(norCon) <= 0. );
259 if ((toreverse && plandab) || (!toreverse && !plandab) ){
260 trans = TopAbs_REVERSED;
261 }
262 else {
263 trans = TopAbs_FORWARD;
264 }
265 if(plandab){
266 Data->ChangeInterferenceOnS2().
267 SetInterference(ChFiKPart_IndexCurveInDS(GCircCon,DStr),
268 trans,GLin2dCon,GLin2dFil2);
269 }
270 else{
271 Data->ChangeInterferenceOnS1().
272 SetInterference(ChFiKPart_IndexCurveInDS(GCircCon,DStr),
273 trans,GLin2dCon,GLin2dFil2);
274 }
275 return Standard_True;
276}