0028828: Modeling Algorithms - New functionalities of BRepFilletAPI_MakeChamfer algorithm
[occt.git] / src / ChFiKPart / ChFiKPart_ComputeData.cxx
CommitLineData
b311480e 1// Created on: 1993-12-23
2// Created by: Isabelle GRIGNON
3// Copyright (c) 1993-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 <BRepAdaptor_HSurface.hxx>
20#include <ChFiDS_ChamfSpine.hxx>
21#include <ChFiDS_FilSpine.hxx>
22#include <ChFiDS_Spine.hxx>
23#include <ChFiDS_SurfData.hxx>
24#include <ChFiKPart_ComputeData.hxx>
25#include <ChFiKPart_ComputeData_ChAsymPlnCon.hxx>
26#include <ChFiKPart_ComputeData_ChAsymPlnCyl.hxx>
27#include <ChFiKPart_ComputeData_ChAsymPlnPln.hxx>
28#include <ChFiKPart_ComputeData_ChPlnCon.hxx>
29#include <ChFiKPart_ComputeData_ChPlnCyl.hxx>
30#include <ChFiKPart_ComputeData_ChPlnPln.hxx>
31#include <ChFiKPart_ComputeData_CS.hxx>
32#include <ChFiKPart_ComputeData_Fcts.hxx>
33#include <ChFiKPart_ComputeData_FilPlnCon.hxx>
34#include <ChFiKPart_ComputeData_FilPlnCyl.hxx>
35#include <ChFiKPart_ComputeData_FilPlnPln.hxx>
36#include <ChFiKPart_ComputeData_Rotule.hxx>
37#include <ChFiKPart_ComputeData_Sphere.hxx>
7fd59977 38#include <ElCLib.hxx>
39#include <ElSLib.hxx>
42cf5bc1 40#include <Geom2d_BSplineCurve.hxx>
41#include <Geom2d_Circle.hxx>
7fd59977 42#include <Geom2d_Curve.hxx>
43#include <Geom2d_Line.hxx>
42cf5bc1 44#include <Geom2dAdaptor_Curve.hxx>
45#include <Geom2dInt_GInter.hxx>
46#include <Geom_Circle.hxx>
47#include <Geom_ConicalSurface.hxx>
7fd59977 48#include <Geom_Curve.hxx>
42cf5bc1 49#include <Geom_CylindricalSurface.hxx>
7fd59977 50#include <Geom_Line.hxx>
7fd59977 51#include <Geom_Plane.hxx>
7fd59977 52#include <Geom_SphericalSurface.hxx>
42cf5bc1 53#include <Geom_Surface.hxx>
54#include <Geom_ToroidalSurface.hxx>
7fd59977 55#include <GeomAbs_CurveType.hxx>
56#include <GeomAbs_SurfaceType.hxx>
57#include <GeomAdaptor_Curve.hxx>
42cf5bc1 58#include <gp.hxx>
59#include <gp_Ax2.hxx>
60#include <gp_Ax3.hxx>
61#include <gp_Circ.hxx>
62#include <gp_Cylinder.hxx>
63#include <gp_Dir.hxx>
64#include <gp_Dir2d.hxx>
65#include <gp_Lin.hxx>
66#include <gp_Lin2d.hxx>
67#include <gp_Pln.hxx>
68#include <gp_Pnt.hxx>
69#include <gp_Pnt2d.hxx>
70#include <gp_Vec.hxx>
71#include <IntAna_QuadQuadGeo.hxx>
72#include <IntRes2d_IntersectionPoint.hxx>
73#include <IntRes2d_Position.hxx>
7fd59977 74#include <IntRes2d_Transition.hxx>
75#include <IntRes2d_TypeTrans.hxx>
42cf5bc1 76#include <IntSurf_Transition.hxx>
77#include <IntSurf_TypeTrans.hxx>
78#include <Precision.hxx>
79#include <Standard_ConstructionError.hxx>
80#include <Standard_NotImplemented.hxx>
7fd59977 81#include <TopExp.hxx>
7fd59977 82#include <TopOpeBRepDS_Curve.hxx>
42cf5bc1 83#include <TopOpeBRepDS_DataStructure.hxx>
7fd59977 84#include <TopOpeBRepDS_Surface.hxx>
85
42cf5bc1 86//#include <BRepAdaptor_Curve2d.hxx>
87//#include <BRepAdaptor_HCurve2d.hxx>
7fd59977 88//=======================================================================
89//function : Compute
90//purpose :
91//=======================================================================
92 Standard_Boolean ChFiKPart_ComputeData::Compute
93 (TopOpeBRepDS_DataStructure& DStr,
94 Handle(ChFiDS_SurfData)& Data,
857ffd5e 95 const Handle(Adaptor3d_HSurface)& S1,
96 const Handle(Adaptor3d_HSurface)& S2,
7fd59977 97 const TopAbs_Orientation Or1,
98 const TopAbs_Orientation Or2,
99 const Handle(ChFiDS_Spine)& Sp,
100 const Standard_Integer Iedge)
101{
102 Standard_Real Wref = 0.;
103
104 Handle(ChFiDS_FilSpine) Spine = Handle(ChFiDS_FilSpine)::DownCast(Sp);
105 Handle(ChFiDS_ChamfSpine) CSpine = Handle(ChFiDS_ChamfSpine)::DownCast(Sp);
7fd59977 106 Standard_Boolean surfok = Standard_False;
7fd59977 107 GeomAbs_SurfaceType typ1 = S1->GetType();
108 GeomAbs_SurfaceType typ2 = S2->GetType();
109 GeomAbs_CurveType ctyp;
110
111 if (!Spine.IsNull())
112 ctyp = Spine->CurrentElementarySpine(Iedge).GetType();
113 else
114 ctyp = CSpine->CurrentElementarySpine(Iedge).GetType();
115
81bba717 116 // Return orientations.
7fd59977 117 TopAbs_Orientation OrFace1 = TopAbs_FORWARD, OrFace2 = TopAbs_FORWARD;
118 Handle(BRepAdaptor_HSurface) HS = Handle(BRepAdaptor_HSurface)::DownCast(S1);
119 if (!HS.IsNull()) OrFace1 = HS->ChangeSurface().Face().Orientation();
120 HS = Handle(BRepAdaptor_HSurface)::DownCast(S2);
121 if (!HS.IsNull()) OrFace2 = HS->ChangeSurface().Face().Orientation();
122
123 if(!Spine.IsNull()){
124 Standard_Real Radius = Spine->Radius(Iedge);
125 if ( typ1 == GeomAbs_Plane && typ2 == GeomAbs_Plane ){
126 surfok = ChFiKPart_MakeFillet(DStr,Data,S1->Plane(),S2->Plane(),
127 Or1,Or2,Radius,Spine->Line(),
128 Wref,OrFace1);
129 }
130 else if ( typ1 == GeomAbs_Plane && typ2 == GeomAbs_Cylinder ){
131 if (ctyp == GeomAbs_Line)
132 surfok = ChFiKPart_MakeFillet(DStr,Data,S1->Plane(),S2->Cylinder(),
133 S2->FirstUParameter(),S2->LastUParameter(),
134 Or1,Or2,Radius,Spine->Line(),
135 Wref,OrFace1,Standard_True);
136 else
137 surfok = ChFiKPart_MakeFillet(DStr,Data,S1->Plane(),S2->Cylinder(),
138 S2->FirstUParameter(),S2->LastUParameter(),
139 Or1,Or2,Radius,Spine->Circle(),
140 Wref,OrFace1,Standard_True);
141 }
142 else if ( typ1 == GeomAbs_Cylinder && typ2 == GeomAbs_Plane ){
143 if (ctyp == GeomAbs_Line)
144 surfok = ChFiKPart_MakeFillet(DStr,Data,S2->Plane(),S1->Cylinder(),
145 S1->FirstUParameter(),S1->LastUParameter(),
146 Or2,Or1,Radius,Spine->Line(),
147 Wref,OrFace2,Standard_False);
148 else
149 surfok = ChFiKPart_MakeFillet(DStr,Data,S2->Plane(),S1->Cylinder(),
150 S1->FirstUParameter(),S1->LastUParameter(),
151 Or2,Or1,Radius,Spine->Circle(),
152 Wref,OrFace2,Standard_False);
153 }
154 else if ( typ1 == GeomAbs_Plane && typ2 == GeomAbs_Cone ){
155 surfok = ChFiKPart_MakeFillet(DStr,Data,S1->Plane(),S2->Cone(),
156 S2->FirstUParameter(),S2->LastUParameter(),
157 Or1,Or2,Radius,Spine->Circle(),
158 Wref,OrFace1,Standard_True);
159 }
160 else if ( typ1 == GeomAbs_Cone && typ2 == GeomAbs_Plane ){
161 surfok = ChFiKPart_MakeFillet(DStr,Data,S2->Plane(),S1->Cone(),
162 S1->FirstUParameter(),S1->LastUParameter(),
163 Or2,Or1,Radius,Spine->Circle(),
164 Wref,OrFace2,Standard_False);
165 }
166 else{
9775fa61 167 throw Standard_NotImplemented("particular case not written");
7fd59977 168 }
169 }
170 else if(!CSpine.IsNull()){
1d54b807 171
172 ChFiDS_ChamfMode aMode = CSpine->Mode();
173
7fd59977 174 if (CSpine->IsChamfer() == ChFiDS_Sym) {
175 Standard_Real dis;
176 CSpine->GetDist(dis);
1d54b807 177
7fd59977 178 if ( typ1 == GeomAbs_Plane && typ2 == GeomAbs_Plane ){
1d54b807 179 surfok = ChFiKPart_MakeChamfer(DStr,Data,aMode,
180 S1->Plane(),S2->Plane(),
181 Or1,Or2,dis, dis,CSpine->Line(),
182 Wref,OrFace1);
7fd59977 183 }
184 else if ( typ1 == GeomAbs_Plane && typ2 == GeomAbs_Cylinder ){
185 if (ctyp == GeomAbs_Circle)
1d54b807 186 surfok = ChFiKPart_MakeChamfer(DStr,Data,aMode,
187 S1->Plane(),S2->Cylinder(),
7fd59977 188 S2->FirstUParameter(),S2->LastUParameter(),
189 Or1,Or2,dis,dis ,CSpine->Circle(),
190 Wref,OrFace1,Standard_True);
191 else
1d54b807 192 surfok = ChFiKPart_MakeChamfer(DStr,Data,aMode,
193 S1->Plane(),S2->Cylinder(),
7fd59977 194 S2->FirstUParameter(),S2->LastUParameter(),
195 Or1,Or2,dis,dis,CSpine->Line(),
196 Wref,OrFace1,Standard_True);
197 }
198 else if ( typ1 == GeomAbs_Cylinder && typ2 == GeomAbs_Plane ){
199 if (ctyp == GeomAbs_Circle)
1d54b807 200 surfok = ChFiKPart_MakeChamfer(DStr,Data,aMode,
201 S2->Plane(),S1->Cylinder(),
7fd59977 202 S1->FirstUParameter(),S1->LastUParameter(),
203 Or2,Or1,dis,dis,CSpine->Circle(),
204 Wref,OrFace2,Standard_False);
205 else
1d54b807 206 surfok = ChFiKPart_MakeChamfer(DStr,Data,aMode,
207 S2->Plane(),S1->Cylinder(),
7fd59977 208 S1->FirstUParameter(),S1->LastUParameter(),
209 Or2,Or1,dis,dis,CSpine->Line(),
210 Wref,OrFace2,Standard_False);
211 }
212 else if ( typ1 == GeomAbs_Plane && typ2 == GeomAbs_Cone ){
1d54b807 213 surfok = ChFiKPart_MakeChamfer(DStr,Data,aMode,
214 S1->Plane(),S2->Cone(),
7fd59977 215 S2->FirstUParameter(),S2->LastUParameter(),
216 Or1,Or2,dis,dis,CSpine->Circle(),
217 Wref,OrFace1,Standard_True);
218 }
219 else if ( typ1 == GeomAbs_Cone && typ2 == GeomAbs_Plane ){
1d54b807 220 surfok = ChFiKPart_MakeChamfer(DStr,Data,aMode,
221 S2->Plane(),S1->Cone(),
7fd59977 222 S1->FirstUParameter(),S1->LastUParameter(),
223 Or2,Or1,dis,dis,CSpine->Circle(),
224 Wref,OrFace2,Standard_False);
225 }
226 else{
9775fa61 227 throw Standard_NotImplemented("particular case not written");
7fd59977 228 }
229 }
230 else if (CSpine->IsChamfer() == ChFiDS_TwoDist) {
231 Standard_Real dis1,dis2;
232 CSpine->Dists(dis1,dis2);
233 if ( typ1 == GeomAbs_Plane && typ2 == GeomAbs_Plane ){
1d54b807 234 surfok = ChFiKPart_MakeChamfer(DStr,Data,aMode,
235 S1->Plane(),S2->Plane(),
236 Or1,Or2,dis1,dis2,CSpine->Line(),
237 Wref,OrFace1);
7fd59977 238 }
239 else if ( typ1 == GeomAbs_Plane && typ2 == GeomAbs_Cylinder ){
240 if (ctyp == GeomAbs_Circle)
1d54b807 241 surfok = ChFiKPart_MakeChamfer(DStr,Data,aMode,
242 S1->Plane(),S2->Cylinder(),
7fd59977 243 S2->FirstUParameter(),S2->LastUParameter(),
244 Or1,Or2,dis1,dis2,CSpine->Circle(),
245 Wref,OrFace1,Standard_True);
246 else
1d54b807 247 surfok = ChFiKPart_MakeChamfer(DStr,Data,aMode,
248 S1->Plane(),S2->Cylinder(),
7fd59977 249 S2->FirstUParameter(),S2->LastUParameter(),
250 Or1,Or2,dis1,dis2,CSpine->Line(),
251 Wref,OrFace1,Standard_True);
252 }
253 else if ( typ1 == GeomAbs_Cylinder && typ2 == GeomAbs_Plane ){
254 if (ctyp == GeomAbs_Circle)
1d54b807 255 surfok = ChFiKPart_MakeChamfer(DStr,Data,aMode,
256 S2->Plane(),S1->Cylinder(),
7fd59977 257 S1->FirstUParameter(),S1->LastUParameter(),
258 Or2,Or1,dis2,dis1,CSpine->Circle(),
259 Wref,OrFace2,Standard_False);
260 else
1d54b807 261 surfok = ChFiKPart_MakeChamfer(DStr,Data,aMode,
262 S2->Plane(),S1->Cylinder(),
7fd59977 263 S1->FirstUParameter(),S1->LastUParameter(),
264 Or2,Or1,dis2,dis1,CSpine->Line(),
265 Wref,OrFace2,Standard_False);
266 }
267 else if ( typ1 == GeomAbs_Plane && typ2 == GeomAbs_Cone ){
1d54b807 268 surfok = ChFiKPart_MakeChamfer(DStr,Data,aMode,
269 S1->Plane(),S2->Cone(),
7fd59977 270 S2->FirstUParameter(),S2->LastUParameter(),
271 Or1,Or2,dis1,dis2,CSpine->Circle(),
272 Wref,OrFace1,Standard_True);
273 }
274 else if ( typ1 == GeomAbs_Cone && typ2 == GeomAbs_Plane ){
1d54b807 275 surfok = ChFiKPart_MakeChamfer(DStr,Data,aMode,
276 S2->Plane(),S1->Cone(),
7fd59977 277 S1->FirstUParameter(),S1->LastUParameter(),
1d54b807 278 Or2,Or1,dis1,dis2,CSpine->Circle(),
7fd59977 279 Wref,OrFace2,Standard_False);
280 }
281 else{
9775fa61 282 throw Standard_NotImplemented("particular case not written");
7fd59977 283 }
284 }
285 else {
286 Standard_Real dis, Angle;
1d54b807 287 Standard_Boolean DisOnP = Standard_True;
288 CSpine->GetDistAngle(dis, Angle);
7fd59977 289 if ( typ1 == GeomAbs_Plane && typ2 == GeomAbs_Plane ){
290 surfok = ChFiKPart_MakeChAsym(DStr,Data,S1->Plane(),S2->Plane(),
291 Or1,Or2, dis, Angle, CSpine->Line(),
292 Wref,OrFace1, DisOnP);
293 }
294 else if ( typ1 == GeomAbs_Plane && typ2 == GeomAbs_Cylinder ){
295 if (ctyp == GeomAbs_Circle)
296 surfok = ChFiKPart_MakeChAsym(DStr,Data,S1->Plane(),S2->Cylinder(),
297 S2->FirstUParameter(),S2->LastUParameter(),
298 Or1,Or2,dis, Angle, CSpine->Circle(),
299 Wref,OrFace1,Standard_True, DisOnP);
300 else
301 surfok = ChFiKPart_MakeChAsym(DStr,Data,S1->Plane(),S2->Cylinder(),
302 S2->FirstUParameter(),S2->LastUParameter(),
303 Or1,Or2, dis, Angle, CSpine->Line(),
304 Wref,OrFace1,Standard_True, DisOnP);
305 }
306 else if ( typ1 == GeomAbs_Cylinder && typ2 == GeomAbs_Plane ){
307 if (ctyp == GeomAbs_Circle)
308 surfok = ChFiKPart_MakeChAsym(DStr,Data,S2->Plane(),S1->Cylinder(),
309 S1->FirstUParameter(),S1->LastUParameter(),
310 Or2,Or1,dis, Angle, CSpine->Circle(),
311 Wref,OrFace2,Standard_False, DisOnP);
312 else
313 surfok = ChFiKPart_MakeChAsym(DStr,Data,S2->Plane(),S1->Cylinder(),
314 S1->FirstUParameter(),S1->LastUParameter(),
315 Or2,Or1,dis, Angle, CSpine->Line(),
316 Wref,OrFace2,Standard_False, DisOnP);
317 }
318 else if ( typ1 == GeomAbs_Plane && typ2 == GeomAbs_Cone ){
319 surfok = ChFiKPart_MakeChAsym(DStr,Data,S1->Plane(),S2->Cone(),
320 S2->FirstUParameter(),S2->LastUParameter(),
321 Or1,Or2, dis, Angle, CSpine->Circle(),
322 Wref,OrFace1,Standard_True, DisOnP);
323 }
324 else if ( typ1 == GeomAbs_Cone && typ2 == GeomAbs_Plane ){
325 surfok = ChFiKPart_MakeChAsym(DStr,Data,S2->Plane(),S1->Cone(),
326 S1->FirstUParameter(),S1->LastUParameter(),
327 Or2,Or1, dis, Angle, CSpine->Circle(),
328 Wref,OrFace2,Standard_False, DisOnP);
329 }
330 else{
9775fa61 331 throw Standard_NotImplemented("particular case not written");
7fd59977 332 }
333 }
334 }
335 return surfok;
336}
337
338//=======================================================================
339//function : ComputeCorner
340//purpose :
341//=======================================================================
342
343Standard_Boolean ChFiKPart_ComputeData::ComputeCorner
344 (TopOpeBRepDS_DataStructure& DStr,
345 const Handle(ChFiDS_SurfData)& Data,
346 const Handle(Adaptor3d_HSurface)& S1,
347 const Handle(Adaptor3d_HSurface)& S2,
348 const TopAbs_Orientation OrFace1,
349 const TopAbs_Orientation,
350 const TopAbs_Orientation Or1,
351 const TopAbs_Orientation Or2,
352 const Standard_Real minRad,
353 const Standard_Real majRad,
354 const gp_Pnt2d& P1S1,
355 const gp_Pnt2d& P2S1,
356 const gp_Pnt2d& P1S2,
357 const gp_Pnt2d& P2S2)
358{
359 Standard_Boolean surfok;
360 GeomAbs_SurfaceType typ1 = S1->GetType();
361 GeomAbs_SurfaceType typ2 = S2->GetType();
362 if ( typ1 != GeomAbs_Plane ){
9775fa61 363 throw Standard_ConstructionError("la face du conge torique doit etre plane");
7fd59977 364 }
81bba717 365 // The guideline is the circle corresponding
366 // to the section of S2, and other construction elements.
7fd59977 367
368 gp_Cylinder cyl;
369 gp_Circ circ;
370 Standard_Real First,Last,fu,lu;
371 ChFiKPart_CornerSpine(S1,S2,P1S1,P2S1,P1S2,P2S2,majRad,cyl,circ,First,Last);
372 if ( typ2 == GeomAbs_Cylinder ){
373 cyl = S2->Cylinder();
374 fu = P1S2.X();
375 lu = P2S2.X();
376 }
377 else{
378 fu = First;
379 lu = Last;
380 }
381 surfok = ChFiKPart_MakeFillet(DStr,Data,S1->Plane(),cyl,
382 fu,lu,Or1,Or2,minRad,circ,
383 First,OrFace1,Standard_True);
384 if(surfok){
385 if ( typ2 != GeomAbs_Cylinder ){
386 Data->ChangeInterferenceOnS2().ChangePCurveOnFace() =
387 ChFiKPart_PCurve(P1S2,P2S2,First,Last);
388 }
389 Data->ChangeVertexFirstOnS1().SetPoint(S1->Value(P1S1.X(),P1S1.Y()));
390 Data->ChangeVertexLastOnS1().SetPoint(S1->Value(P2S1.X(),P2S1.Y()));
391 Data->ChangeVertexFirstOnS2().SetPoint(S2->Value(P1S2.X(),P1S2.Y()));
392 Data->ChangeVertexLastOnS2().SetPoint(S2->Value(P2S2.X(),P2S2.Y()));
393 Data->ChangeInterferenceOnS1().SetFirstParameter(First);
394 Data->ChangeInterferenceOnS1().SetLastParameter(Last);
395 Data->ChangeInterferenceOnS2().SetFirstParameter(First);
396 Data->ChangeInterferenceOnS2().SetLastParameter(Last);
397 return Standard_True;
398 }
399 return Standard_False;
400}
401
402
403//=======================================================================
404//function : ComputeCorner
405//purpose :
406//=======================================================================
407
408Standard_Boolean ChFiKPart_ComputeData::ComputeCorner
409 (TopOpeBRepDS_DataStructure& DStr,
410 const Handle(ChFiDS_SurfData)& Data,
411 const Handle(Adaptor3d_HSurface)& S1,
412 const Handle(Adaptor3d_HSurface)& S2,
413 const TopAbs_Orientation OrFace1,
414 const TopAbs_Orientation OrFace2,
415 const TopAbs_Orientation Or1,
416 const TopAbs_Orientation Or2,
417 const Standard_Real Rad,
418 const gp_Pnt2d& PS1,
419 const gp_Pnt2d& P1S2,
420 const gp_Pnt2d& P2S2)
421{
422 return ChFiKPart_Sphere(DStr,Data,S1,S2,OrFace1,OrFace2,Or1,Or2,Rad,PS1,P1S2,P2S2);
423}
424
425//=======================================================================
426//function : ComputeCorner
427//purpose :
428//=======================================================================
429
430Standard_Boolean ChFiKPart_ComputeData::ComputeCorner
431 (TopOpeBRepDS_DataStructure& DStr,
432 const Handle(ChFiDS_SurfData)& Data,
433 const Handle(Adaptor3d_HSurface)& S,
434 const Handle(Adaptor3d_HSurface)& S1,
435 const Handle(Adaptor3d_HSurface)& S2,
436 const TopAbs_Orientation OfS,
437 const TopAbs_Orientation OS,
438 const TopAbs_Orientation OS1,
439 const TopAbs_Orientation OS2,
440 const Standard_Real Radius)
441{
442 GeomAbs_SurfaceType typ = S->GetType();
443 GeomAbs_SurfaceType typ1 = S1->GetType();
444 GeomAbs_SurfaceType typ2 = S2->GetType();
445 if (typ != GeomAbs_Plane ||
446 typ1 != GeomAbs_Plane ||
447 typ2 != GeomAbs_Plane){
9775fa61 448 throw Standard_ConstructionError("torus joint only between the planes");
7fd59977 449 }
450 return ChFiKPart_MakeRotule(DStr,Data,S->Plane(),S1->Plane(),
451 S2->Plane(),OS,OS1,OS2,Radius,OfS);
452}