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 | |
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_Line.hxx> |
7fd59977 |
29 | #include <Geom_SphericalSurface.hxx> |
42cf5bc1 |
30 | #include <Geom_ToroidalSurface.hxx> |
31 | #include <gp.hxx> |
32 | #include <gp_Ax2.hxx> |
33 | #include <gp_Ax3.hxx> |
34 | #include <gp_Circ.hxx> |
35 | #include <gp_Cone.hxx> |
36 | #include <gp_Dir.hxx> |
37 | #include <gp_Dir2d.hxx> |
38 | #include <gp_Lin.hxx> |
39 | #include <gp_Lin2d.hxx> |
40 | #include <gp_Pln.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 | //======================================================================= |
49 | //function : MakeFillet |
81bba717 |
50 | //purpose : case cone/plane or plane/cone. |
7fd59977 |
51 | //======================================================================= |
7fd59977 |
52 | Standard_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 | } |