0028828: Modeling Algorithms - New functionalities of BRepFilletAPI_MakeChamfer algorithm
[occt.git] / src / ChFiKPart / ChFiKPart_ComputeData_ChPlnCyl.cxx
1 // Created on: 1995-05-19
2 // Created by: Flore Lantheaume
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
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>
23 #include <ElCLib.hxx>
24 #include <ElSLib.hxx>
25 #include <Geom2d_Circle.hxx>
26 #include <Geom2d_Line.hxx>
27 #include <Geom_Circle.hxx>
28 #include <Geom_ConicalSurface.hxx>
29 #include <Geom_CylindricalSurface.hxx>
30 #include <Geom_Line.hxx>
31 #include <Geom_Plane.hxx>
32 #include <gp.hxx>
33 #include <gp_Ax2.hxx>
34 #include <gp_Ax3.hxx>
35 #include <gp_Ax22d.hxx>
36 #include <gp_Circ.hxx>
37 #include <gp_Circ2d.hxx>
38 #include <gp_Dir.hxx>
39 #include <gp_Dir2d.hxx>
40 #include <gp_Lin2d.hxx>
41 #include <gp_Pnt.hxx>
42 #include <gp_Pnt2d.hxx>
43 #include <gp_Vec.hxx>
44 #include <IntAna_QuadQuadGeo.hxx>
45 #include <Precision.hxx>
46 #include <TopOpeBRepDS_DataStructure.hxx>
47
48 //pour tester
49 //=======================================================================
50 //function : MakeChamfer
51 //purpose  : Compute the chamfer in the particular case Plane/Cylinder
52 //           or Cylinder/Plane
53 //           Compute the SurfData <Data> of the chamfer build on the <Spine>
54 //           between the plane <Pln> and the cylinder <Cyl>, with the 
55 //           distances <Dis1> on <Pln> and <Dis2> on <Cyl>.
56 //           <Or1> and <Or2> are the orientations of <Pln> and <Cyl>
57 //           and <Ofpl> this of the face carried by <Pln>.
58 //           <First> is the start point on the <Spine>
59 //           <Plandab> is equal to True if the plane is the surface S1
60 //           <fu> and <lu> are the first and last u parameters of the
61 //           cylinder
62 //out      : True if the chanfer has been computed
63 //           False else
64 //=======================================================================
65 Standard_Boolean ChFiKPart_MakeChamfer(TopOpeBRepDS_DataStructure& DStr,
66                                        const Handle(ChFiDS_SurfData)& Data,
67                                        const ChFiDS_ChamfMode theMode,
68                                        const gp_Pln& Pln, 
69                                        const gp_Cylinder& Cyl, 
70                                        const Standard_Real fu,
71                                        const Standard_Real lu,
72                                        const TopAbs_Orientation Or1,
73                                        const TopAbs_Orientation Or2,
74                                        const Standard_Real theDis1, 
75                                        const Standard_Real theDis2,
76                                        const gp_Circ& Spine, 
77                                        const Standard_Real First, 
78                                        const TopAbs_Orientation Ofpl,
79                                        const Standard_Boolean plandab)
80 {
81
82   // compute the chamfer surface(cone)
83
84   Standard_Real Dis1 = theDis1, Dis2 = theDis2;
85   if (theMode == ChFiDS_ConstThroatChamfer)
86     Dis1 = Dis2 = theDis1 * sqrt(2.);
87   else if (theMode == ChFiDS_ConstThroatWithPenetrationChamfer)
88   {
89     Standard_Real aDis2 = Min(theDis1, theDis2);
90     Standard_Real aDis1 = Max(theDis1, theDis2);
91     Dis2 = sqrt(aDis1*aDis1 - aDis2*aDis2);
92     Dis1 = aDis1*aDis1/aDis2 - aDis2;
93   }
94
95     // compute the normals to the plane surface & to the plane face
96   gp_Ax3 PosPl = Pln.Position();
97   gp_Dir Dpl = PosPl.XDirection().Crossed(PosPl.YDirection());
98   gp_Dir norf = Dpl;
99   if ( Ofpl == TopAbs_REVERSED) norf.Reverse();
100   if (Or1 == TopAbs_REVERSED) Dpl.Reverse();
101
102     // compute the origin Or of the cone
103   gp_Pnt Or = Cyl.Location();
104   Standard_Real u,v;
105   ElSLib::PlaneParameters(PosPl,Or,u,v);
106   gp_Pnt2d pt2dPln(u,v);
107   ElSLib::PlaneD0(u,v,PosPl,Or);
108   gp_Pnt PtPl = Or;  // projection of the cylinder origin 
109                      //on the plane 
110
111   gp_Pnt PtSp;//start 3d point on the Spine 
112   gp_Vec DSp; //tangent vector to the spine on PtSp
113   ElCLib::D1(First,Spine,PtSp,DSp);
114   gp_Dir Dx(gp_Vec(Or,PtSp));
115   gp_Dir Dy(DSp);
116   ElSLib::Parameters(Cyl,PtSp,u,v);
117   gp_Pnt PtCyl;//point on the cylinder and on the Spine
118   gp_Vec Vu,Vv;
119   ElSLib::D1(u,v,Cyl,PtCyl,Vu,Vv);
120   gp_Dir Dcyl(Vu.Crossed(Vv));//normal to the cylinder in PtSp
121   if (Or2 == TopAbs_REVERSED) Dcyl.Reverse();
122   Standard_Boolean dedans = ( Dcyl.Dot(Dx) <= 0.);
123
124   Standard_Boolean pointu = Standard_False;
125   Standard_Real ConRad, Rad, SemiAngl ;
126   Or.SetCoord(Or.X()+Dis2*Dpl.X(),
127               Or.Y()+Dis2*Dpl.Y(),
128               Or.Z()+Dis2*Dpl.Z());
129
130       // variables used to compute the semiangle of the cone
131   gp_Dir Vec1(Or.X()-PtPl.X(), Or.Y()-PtPl.Y(), Or.Z()-PtPl.Z()); 
132   gp_Pnt Pt(Or.X()+Dis1*PosPl.XDirection().X(),
133             Or.Y()+Dis1*PosPl.XDirection().Y(),
134             Or.Z()+Dis1*PosPl.XDirection().Z());
135   gp_Dir Vec2( Pt.X()-PtPl.X(), Pt.Y()-PtPl.Y(), Pt.Z()-PtPl.Z());
136
137       // compute the parameters of the conical surface
138   if (dedans) {
139     Rad = Cyl.Radius()- Dis1;
140     if ( Abs(Rad) <= Precision::Confusion() ) pointu = Standard_True;
141     if(Rad < 0 ) {
142 #ifdef OCCT_DEBUG
143       cout<<"the chamfer can't pass"<<endl;
144 #endif
145       return Standard_False;
146     }
147   }
148   else {
149     Rad = Cyl.Radius()+Dis1;
150     gp_Dir Dplr = Dpl.Reversed();
151     Dpl = Dplr;
152    }
153   ConRad = Cyl.Radius();
154   SemiAngl = Vec1.Angle(Vec2);
155   gp_Ax3 ConAx3(Or,Dpl,Dx);
156
157   Handle (Geom_ConicalSurface)
158     gcon = new Geom_ConicalSurface( ConAx3, SemiAngl, ConRad );
159
160     // changes due to the fact the parameters of the chamfer must go increasing
161     // from surface S1 to surface S2
162   if ( (dedans && !plandab) || (!dedans && plandab) ) {
163     gcon->VReverse();// be carefull : the SemiAngle was changed
164     ConAx3 = gcon->Position();
165     SemiAngl = gcon->SemiAngle();
166   }
167
168       // changes due to the fact we have reversed the V direction of 
169       // parametrization
170   if (ConAx3.YDirection().Dot(DSp) <= 0.) {
171     ConAx3.YReverse();
172     gcon->SetPosition(ConAx3);
173   }
174
175   Data->ChangeSurf(ChFiKPart_IndexSurfaceInDS(gcon,DStr));
176
177
178   // compute the chamfer's orientation according to the orientation
179   // of the faces
180
181     //search the normal to the cone
182
183   gp_Vec deru, derv;
184   ElSLib::ConeD1(0.,0.,ConAx3,ConRad,SemiAngl,Pt,deru,derv);
185
186   gp_Dir norCon(deru.Crossed(derv));
187   
188   Standard_Boolean toreverse = ( norCon.Dot(norf) <= 0.);
189   if (toreverse) {
190     Data->ChangeOrientation() = TopAbs_REVERSED; 
191   }
192   else {
193     Data->ChangeOrientation() = TopAbs_FORWARD; 
194   }
195   
196   //we load of the faceInterference with the pcurves and
197   // the 3d curves
198
199     // Case of the plane face
200     // NB: in the case 'pointu', no pcurve on the plane surface
201     // and no intersection plane-chamfer are needed
202   Handle(Geom2d_Circle) GCir2dPln;
203   Handle(Geom_Circle) GCirPln;
204   gp_Ax2 CirAx2 = ConAx3.Ax2();
205   CirAx2.SetLocation(PtPl);
206
207   if (!pointu) {
208
209       // intersection plane-chamfer
210     gp_Circ CirPln(CirAx2,Rad);
211     GCirPln = new Geom_Circle(CirPln);
212
213       //pcurve on the plane
214     ElSLib::PlaneParameters(PosPl,Pt ,u,v);
215     gp_Pnt2d p2dPln(u,v);
216     gp_Dir2d d2d(DSp.Dot(PosPl.XDirection()),DSp.Dot(PosPl.YDirection()));
217     gp_Ax22d ax2dPln(pt2dPln, gp_Dir2d(gp_Vec2d(pt2dPln,p2dPln)),d2d);
218     gp_Circ2d cir2dPln(ax2dPln,Rad);
219     GCir2dPln = new Geom2d_Circle(cir2dPln);
220   }
221
222       //pcurve on the chamfer
223   gp_Pnt2d p2dch;
224   if (plandab) 
225     v= -sqrt(Dis1*Dis1+Dis2*Dis2);
226   else 
227     v = sqrt(Dis1*Dis1+Dis2*Dis2);
228   p2dch.SetCoord(0.,v);
229   ElSLib::ConeD1(0.,v,ConAx3,ConRad,SemiAngl,Pt,deru,derv);
230   gp_Lin2d lin2dch(p2dch,gp::DX2d());
231   Handle(Geom2d_Line) GLin2dCh1 = new Geom2d_Line(lin2dch);
232
233       //orientation
234   TopAbs_Orientation trans; 
235   gp_Dir norpl = PosPl.XDirection().Crossed(PosPl.YDirection());
236   toreverse = ( norCon.Dot(norpl) <= 0. );
237   if ((toreverse && plandab) || (!toreverse && !plandab)){ 
238     trans = TopAbs_FORWARD;
239   }
240   else { 
241     trans = TopAbs_REVERSED; 
242   }
243
244
245   if(plandab){
246     Data->ChangeInterferenceOnS1().
247       SetInterference(ChFiKPart_IndexCurveInDS(GCirPln,DStr),
248                       trans,GCir2dPln,GLin2dCh1);
249   }
250   else{
251     Data->ChangeInterferenceOnS2().
252       SetInterference(ChFiKPart_IndexCurveInDS(GCirPln,DStr),
253                       trans,GCir2dPln,GLin2dCh1);
254   }
255
256     // Case of the cylindrical face
257
258       //intersection cylinder-chamfer
259   CirAx2.SetLocation(Or);
260   gp_Circ CirCyl(CirAx2,ConRad);
261   Handle(Geom_Circle) GCirCyl = new Geom_Circle(CirCyl);
262
263       //pcurve on the chamfer
264   p2dch.SetCoord(0.,0.);
265   ElSLib::ConeD1(0.,0.,ConAx3,ConRad,SemiAngl,Pt,deru,derv);
266   lin2dch.SetLocation(p2dch);
267   Handle(Geom2d_Line) GLin2dCh2 = new Geom2d_Line(lin2dch);
268
269       //pcurve on the cylinder
270   norCon.SetXYZ (deru.Crossed(derv).XYZ());
271
272   Pt.SetCoord(Or.X()+ConRad*Dx.X(),
273               Or.Y()+ConRad*Dx.Y(),
274               Or.Z()+ConRad*Dx.Z());
275   ElSLib::Parameters(Cyl,Pt ,u,v);
276   Standard_Real tol = Precision::PConfusion();
277   Standard_Boolean careaboutsens = 0;
278   if(Abs(lu - fu - 2*M_PI) < tol) careaboutsens = 1;
279   if(u >= fu - tol && u < fu) u = fu;
280   if(u <= lu + tol && u > lu) u = lu;
281   if(u < fu || u > lu) u = ChFiKPart_InPeriod(u,fu,fu + 2*M_PI,tol);
282
283   ElSLib::D1(u,v,Cyl,Pt,deru,derv);
284   gp_Dir norcyl = deru.Crossed(derv);
285   gp_Dir2d d2dCyl = gp::DX2d();
286   if( deru.Dot(Dy) < 0. ){
287     d2dCyl.Reverse(); 
288     if(careaboutsens && Abs(fu-u)<tol) u = lu;
289   }
290   else if(careaboutsens && Abs(lu-u)<tol) u = fu;
291   gp_Pnt2d p2dCyl(u,v);
292   gp_Lin2d lin2dCyl(p2dCyl,d2dCyl);
293   Handle(Geom2d_Line) GLin2dCyl = new Geom2d_Line(lin2dCyl);
294
295       //orientation
296   toreverse = ( norCon.Dot(norcyl) <= 0. );
297   if ((toreverse && plandab) || (!toreverse && !plandab) ) {
298     trans = TopAbs_REVERSED;
299   }
300   else {
301     trans = TopAbs_FORWARD;
302   }
303
304
305   if(plandab){
306     Data->ChangeInterferenceOnS2().
307       SetInterference(ChFiKPart_IndexCurveInDS(GCirCyl,DStr),
308                       trans,GLin2dCyl,GLin2dCh2);
309   }
310   else{
311     Data->ChangeInterferenceOnS1().
312       SetInterference(ChFiKPart_IndexCurveInDS(GCirCyl,DStr),
313                       trans,GLin2dCyl,GLin2dCh2);
314   }
315
316   return Standard_True;
317 }
318
319 //=======================================================================
320 //function : MakeChamfer
321 //purpose  : case cylinder/plane or plane/cylinder.
322 //=======================================================================
323
324 Standard_Boolean ChFiKPart_MakeChamfer(TopOpeBRepDS_DataStructure& DStr,
325                                        const Handle(ChFiDS_SurfData)& Data, 
326                                        const ChFiDS_ChamfMode theMode,
327                                        const gp_Pln& Pln, 
328                                        const gp_Cylinder& Cyl, 
329                                        const Standard_Real /*fu*/,
330                                        const Standard_Real /*lu*/,
331                                        const TopAbs_Orientation Or1,
332                                        const TopAbs_Orientation Or2,
333                                        const Standard_Real dis1,
334                                        const Standard_Real dis2,
335                                        const gp_Lin& Spine, 
336                                        const Standard_Real First, 
337                                        const TopAbs_Orientation Ofpl,
338                                        const Standard_Boolean plandab)
339 {
340   // calculation of the fillet plane.
341   // or1 and or2 permit to determine in which of four sides created by
342   // intersection of 2 surfaces we are
343   //        _|_          Ofpl is orientation of the plane face allowing
344   //         |4          to determine the side of the material
345
346   if (theMode != ChFiDS_ClassicChamfer)
347     return Standard_False;
348   
349   gp_Pnt OrSpine = ElCLib::Value(First,Spine);
350   gp_Pnt POnCyl, POnPln, OrCyl;
351
352   gp_Dir XDir = Spine.Direction();
353   gp_Ax3 AxPln  = Pln.Position();
354   gp_Dir NorPln = AxPln.XDirection().Crossed(AxPln.YDirection());
355   gp_Dir NorF(NorPln);
356   if (Or1 == TopAbs_REVERSED)
357     {NorF.Reverse();} 
358
359   gp_Ax3 AxCyl = Cyl.Position();
360   // OrCyl is the point on axis of cylinder in the plane normal to the
361   // axis containing OrSpine
362   // Project <OrSpine> onto <AxCyl>
363   gp_XYZ AxLoc = AxCyl.Location().XYZ(); //aLine.Location().XYZ();
364   gp_XYZ AxDir = AxCyl.Direction().XYZ();
365   Standard_Real Parameter = (OrSpine.XYZ() - AxLoc) * AxDir;
366   OrCyl.SetXYZ( AxLoc + Parameter * AxDir );
367  
368   //construction of POnPln
369   gp_Vec VecTranslPln,tmp;
370
371   tmp = gp_Vec(OrSpine,OrCyl);
372   if ((Or2 == TopAbs_FORWARD && Cyl.Direct()) ||
373       (Or2 == TopAbs_REVERSED && !Cyl.Direct()))
374     {tmp.Reverse();}
375
376   VecTranslPln = gp_Vec( XDir.Crossed(NorPln) );
377   if( VecTranslPln.Dot(tmp) <= 0. )
378      {VecTranslPln.Reverse();}
379   VecTranslPln.Multiply(dis1);
380
381   POnPln.SetXYZ( (OrSpine.XYZ()).Added(VecTranslPln.XYZ()) );
382
383   //construction of POnCyl 
384   Standard_Real alpha = ( 2*ASin(dis2*0.5/Cyl.Radius()) );
385 //  gp_Vec VecTranslCyl;
386 //  VecTranslCyl = gp_Vec(OrSpine,OrCyl);
387  
388 //  if ( ( XDir.Crossed(gp_Dir(VecTranslCyl)) ).Dot(NorF) <=0. )
389 //    {VecTranslCyl.Rotate(gp_Ax1(OrSpine,XDir),alpha);}
390 //  else
391 //    {VecTranslCyl.Rotate(gp_Ax1(OrSpine,XDir.Reversed()),alpha);}
392
393 //  POnCyl.SetXYZ( OrCyl.XYZ().Added(VecTranslCyl.XYZ()) );
394
395   gp_Vec  VecCylTransl = gp_Vec(OrCyl,OrSpine);
396
397   if ( ( XDir.Crossed(gp_Dir(VecCylTransl)) ).Dot(NorF) > 0.) {
398     VecCylTransl.Rotate(gp_Ax1(OrCyl,XDir),alpha);
399   }
400   else { 
401     VecCylTransl.Rotate(gp_Ax1(OrCyl,XDir.Reversed()),alpha);}
402
403   POnCyl.SetXYZ( OrCyl.XYZ().Added(VecCylTransl.XYZ()) );
404
405   //construction of chamfer  
406   Standard_Real UOnCyl,VOnCyl,UOnPln,VOnPln;
407   ElSLib::Parameters(Cyl,POnCyl,UOnCyl,VOnCyl);
408   POnCyl = ElSLib::CylinderValue(UOnCyl,VOnCyl,AxCyl,Cyl.Radius());             
409   ElSLib::Parameters(Pln,POnPln,UOnPln,VOnPln);
410   POnPln = ElSLib::PlaneValue(UOnPln,VOnPln,AxPln);
411
412   //construction of YDir to go to face1 from face2.
413   gp_Vec YDir(POnPln,POnCyl);
414   if (!plandab){ 
415     YDir.Reverse();
416   }
417   gp_Ax3 AxCh(POnPln,XDir.Crossed(YDir),XDir);
418
419   Handle(Geom_Plane) Chamfer = new Geom_Plane(AxCh);
420   Data->ChangeSurf(ChFiKPart_IndexSurfaceInDS(Chamfer,DStr));
421
422   // FaceInterferences are loaded with pcurves and curves 3d.
423      //----------- edge plane-Chamfer
424   gp_Pnt2d PPln2d(UOnPln,VOnPln);
425   gp_Dir2d VPln2d(XDir.Dot(AxPln.XDirection()),
426                   XDir.Dot(AxPln.YDirection()));
427   gp_Lin2d Lin2dPln(PPln2d,VPln2d);
428
429   POnPln = ElSLib::Value(UOnPln,VOnPln,Pln);
430   gp_Lin   C3d(POnPln,XDir);
431
432   Standard_Real U,VOnChamfer;
433   ElSLib::PlaneParameters(AxCh,POnPln,U,VOnChamfer);
434   gp_Lin2d LOnChamfer(gp_Pnt2d(U,VOnChamfer),gp::DX2d());
435
436   Handle(Geom_Line)   L3d  = new Geom_Line  (C3d);
437   Handle(Geom2d_Line) LFac = new Geom2d_Line(Lin2dPln);
438   Handle(Geom2d_Line) LFil = new Geom2d_Line(LOnChamfer);
439
440   gp_Dir NorFil=AxCh.Direction();
441   Standard_Boolean toreverse = ( NorFil.Dot(NorPln) <= 0. );
442
443   gp_Dir DirPlnCyl(gp_Vec(POnPln, POnCyl));
444   gp_Dir DirSPln(gp_Vec(OrSpine, POnPln));
445   Standard_Boolean PosChamfPln = DirPlnCyl.Dot(DirSPln) > 0;
446
447   if (PosChamfPln )
448     toreverse = !toreverse; 
449   // It is checked if the orientation of the Chamfer is the same as of the plane
450   if (toreverse)
451     {Data->ChangeOrientation() = TopAbs::Reverse(Ofpl);}
452   else          
453     {Data->ChangeOrientation() = Ofpl;}
454
455   TopAbs_Orientation trans = TopAbs_FORWARD;
456   if ((!plandab && toreverse) || (plandab && !toreverse))
457     {trans=TopAbs_REVERSED;}
458   
459   //trans permits to determine the "material" side on S1(2) limited by L3d
460   if (plandab) 
461     {Data->ChangeInterferenceOnS1().
462      SetInterference(ChFiKPart_IndexCurveInDS(L3d,DStr),trans,LFac,LFil);}
463   else    
464     {Data->ChangeInterferenceOnS2().
465      SetInterference(ChFiKPart_IndexCurveInDS(L3d,DStr),trans,LFac,LFil);}
466   
467      //------------edge cylinder-Chamfer        
468   gp_Pnt2d PCyl2d(UOnCyl,VOnCyl);
469   gp_Dir2d VCyl2d=gp::DY2d();
470   if ( XDir.Dot(AxCyl.Direction())<0 )
471     {VCyl2d.Reverse();}
472   gp_Lin2d Lin2dCyl(PCyl2d,VCyl2d);
473
474   POnCyl = ElSLib::Value(UOnCyl,VOnCyl,Cyl);
475   C3d = gp_Lin(POnCyl,XDir);
476
477   ElSLib::PlaneParameters(AxCh,POnCyl,U,VOnChamfer);
478   LOnChamfer = gp_Lin2d(gp_Pnt2d(U,VOnChamfer),gp::DX2d());
479
480   L3d  = new Geom_Line  (C3d);
481   LFac = new Geom2d_Line(Lin2dCyl);
482   LFil = new Geom2d_Line(LOnChamfer);
483
484   gp_Vec deru,derv;            
485   ElSLib::CylinderD1(UOnCyl,VOnCyl,AxCyl,Cyl.Radius(),POnCyl,deru,derv);
486   gp_Dir NorCyl(deru.Crossed(derv));    
487
488   toreverse = ( NorFil.Dot(NorCyl) <= 0. );
489
490   gp_Dir DirSCyl(gp_Vec(OrSpine, POnCyl));
491   Standard_Boolean PosChamfCyl = DirPlnCyl.Dot(DirSCyl) < 0;
492
493
494   if (PosChamfCyl) 
495      toreverse = !toreverse; 
496
497   trans = TopAbs_REVERSED;
498   if ((!plandab && toreverse) || (plandab && !toreverse))
499     {trans=TopAbs_FORWARD;}
500
501   if (plandab) 
502     Data->ChangeInterferenceOnS2().
503     SetInterference(ChFiKPart_IndexCurveInDS(L3d,DStr),trans,LFac,LFil);
504   else    
505     Data->ChangeInterferenceOnS1().
506     SetInterference(ChFiKPart_IndexCurveInDS(L3d,DStr),trans,LFac,LFil);
507   return Standard_True;
508 }       
509   
510
511
512