Warnings on vc14 were eliminated
[occt.git] / src / ChFiKPart / ChFiKPart_ComputeData_ChAsymPlnCon.cxx
CommitLineData
b311480e 1// Created on: 1998-06-18
2// Created by: Philippe NOUAILLE
3// Copyright (c) 1998-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>
28#include <Geom_ConicalSurface.hxx>
29#include <Geom_CylindricalSurface.hxx>
42cf5bc1 30#include <gp.hxx>
31#include <gp_Ax2.hxx>
32#include <gp_Ax3.hxx>
33#include <gp_Circ.hxx>
34#include <gp_Dir.hxx>
35#include <gp_Dir2d.hxx>
36#include <gp_Lin2d.hxx>
37#include <gp_Pnt.hxx>
38#include <gp_Pnt2d.hxx>
39#include <gp_Vec.hxx>
40#include <Precision.hxx>
41#include <TopOpeBRepDS_DataStructure.hxx>
7fd59977 42
43//=======================================================================
44//function : MakeChAsym
45//purpose : Compute the chamfer in the particular case Plane/Cone or
46// Cylinder/Plane
47// Compute the SurfData <Data> of the chamfer build on the <Spine>
48// between the plane <Pln> and the cone <Con>, with the
49// distances <Dis1> on <Pln> and <Dis2> on <Con>.
50// <Or1> and <Or2> are the orientations of <Pln> and <Con>
51// and <Ofpl> this of the face carried by <Pln>.
52// <First> is the start point on the <Spine>
53// <Plandab> is equal to True if the plane is the surface S1
54// <fu> and <lu> are the first and last u parameters of the
55// cone
56//out : True if the chanfer has been computed
57// False else
58//=======================================================================
7fd59977 59Standard_Boolean ChFiKPart_MakeChAsym(TopOpeBRepDS_DataStructure& DStr,
60 const Handle(ChFiDS_SurfData)& Data,
61 const gp_Pln& Pln,
62 const gp_Cone& Con,
63 const Standard_Real fu,
64 const Standard_Real lu,
65 const TopAbs_Orientation Or1,
66 const TopAbs_Orientation Or2,
67 const Standard_Real Dis,
68 const Standard_Real Angle,
69 const gp_Circ& Spine,
70 const Standard_Real First,
71 const TopAbs_Orientation Ofpl,
72 const Standard_Boolean plandab,
73 const Standard_Boolean DisOnP)
74{
75 // Compute the chamfer surface(cone)
76 gp_Ax3 PosPl = Pln.Position();
77 gp_Dir Dpl = PosPl.XDirection().Crossed(PosPl.YDirection());
78 gp_Dir norf = Dpl;
79 if (Ofpl == TopAbs_REVERSED ) norf.Reverse();
80 if ( Or1 == TopAbs_REVERSED ) Dpl.Reverse();
81
82 // compute the origin of the conical chamfer PtPl
83 gp_Pnt Or = Con.Location();
84 Standard_Real u,v;
85 ElSLib::PlaneParameters(PosPl,Or,u,v);
86 gp_Pnt2d pt2dPln(u,v);
87 ElSLib::PlaneD0(u,v,PosPl,Or);
88 gp_Pnt PtPl = Or;
89
90 gp_Pnt PtSp;
91 gp_Vec DSp;
92 ElCLib::D1(First,Spine,PtSp,DSp);
93 gp_Dir Dx(gp_Vec(PtPl,PtSp));
94
95 //compute the normal to the cone in PtSp
96 gp_Vec deru,derv;
97 gp_Pnt PtCon;
98 ElSLib::Parameters(Con,PtSp,u,v);
99 ElSLib::D1(u,v,Con,PtCon ,deru,derv);
100 gp_Dir Dcon( deru.Crossed(derv) );
101 if ( Or2 == TopAbs_REVERSED ) Dcon.Reverse();
102
103 Standard_Boolean dedans = ( Dx.Dot(Dcon) <= 0.);
104 Standard_Boolean ouvert = ( Dpl.Dot(Dcon) >= 0.);
105
106 // variables used to compute the semiangle of the chamfer
107 Standard_Real angCon = Con.SemiAngle();
108 Standard_Real move;
109 Standard_Real ChamfRad,SemiAngl;
110 Standard_Boolean pointu = Standard_False;
111 Standard_Real dis;
112 Standard_Boolean iscylinder = Standard_False;
113 Standard_Boolean isConPar = Standard_False;
114
115 if ( (plandab && DisOnP) || (!plandab && !DisOnP) ) {
116 Standard_Real tgang = Tan(Angle), Dis11;
117 Standard_Real tgCon = Abs(Tan(angCon));
118 if (ouvert) {
119 move = Dis * tgang / (1. - tgCon * tgang);
120 Dis11 = move * tgCon;
121 dis = Dis + Dis11;
122 }
123 else {
124 move = Dis * tgang / (1. + tgCon * tgang);
125 Dis11 = move * tgCon;
126 dis = Dis - Dis11;
127 }
128
129 // compute the parameters of the conical chamfer
130 if (dedans) {
131 ChamfRad = Spine.Radius() - Dis;
132 if ( Abs(ChamfRad) < Precision::Confusion() ) pointu = Standard_True;
133 if( ChamfRad < 0 ) {
0797d9d3 134#ifdef OCCT_DEBUG
81bba717 135 cout<<"the chamfer can't pass"<<endl;
7fd59977 136#endif
137 return Standard_False;
138 }
c6541a0c 139 SemiAngl = M_PI / 2. - Angle;
7fd59977 140 }
141 else {
142 ChamfRad = Spine.Radius() + Dis;
c6541a0c 143 SemiAngl = Angle - M_PI / 2.;
7fd59977 144 }
145
146 if (ouvert) {
147 if (Abs(angCon) - Abs(SemiAngl) > -Precision::Confusion() ) {
0797d9d3 148#ifdef OCCT_DEBUG
81bba717 149 cout<<"wrong choice of angle for the chamfer"<<endl;
63c629aa 150#endif
7fd59977 151 return Standard_False;
152 }
153 }
154 }
155 else {
156 Standard_Real Dis1;
157 move = Dis * Cos(angCon);
158 if (ouvert) {
159 SemiAngl = Abs(angCon) + Angle;
160
c6541a0c 161 if ( (M_PI / 2. - SemiAngl) < Precision::Confusion() ) {
0797d9d3 162#ifdef OCCT_DEBUG
81bba717 163 cout <<"wrong choice of angle for the chamfer"<<endl;
63c629aa 164#endif
7fd59977 165 return Standard_False;
166 }
167 Dis1 = move * Tan(SemiAngl) - Dis * Abs(Sin(angCon));
168
169 if (!dedans) SemiAngl = -SemiAngl;
170
171 }
172 else {
173 SemiAngl = Abs(angCon) - Angle;
174
175 if ( Abs(SemiAngl) < Precision::Confusion() ) {
176 iscylinder = Standard_True;
177 Dis1 = Dis * Abs(Sin(angCon));
178 }
179 else {
180 Dis1 = Dis * Abs(Sin(angCon)) - move * Tan(SemiAngl);
181 }
182
183 if (SemiAngl > Precision::Confusion())
184 isConPar = Standard_True;
185
186 if (dedans) SemiAngl = -SemiAngl;
187
188 }
189
190 // compute the parameters of the conical chamfer
191 if (dedans) {
192 ChamfRad = Spine.Radius() - Dis1;
193
194 if ( Abs(ChamfRad) < Precision::Confusion() ) pointu = Standard_True;
195 if( ChamfRad < 0 ) {
0797d9d3 196#ifdef OCCT_DEBUG
81bba717 197 cout<<"the chamfer can't pass"<<endl;
7fd59977 198#endif
199 return Standard_False;
200 }
201 }
202 else {
203 ChamfRad = Spine.Radius() + Dis1;
204 //Dpl.Reverse();
205 }
206
207 if (ouvert)
208 dis = Dis1 + Dis * Abs(Sin(angCon));
209 else
210 dis = Dis1 - Dis * Abs(Sin(angCon));
211 }
212
213 Or.SetCoord( Or.X()+ move*Dpl.X(),
214 Or.Y()+ move*Dpl.Y(),
215 Or.Z()+ move*Dpl.Z());
216 gp_Pnt Pt(Or.X()+dis*PosPl.XDirection().X(),
217 Or.Y()+dis*PosPl.XDirection().Y(),
218 Or.Z()+dis*PosPl.XDirection().Z());
219
220 gp_Ax3 ChamfAx3(PtPl,Dpl,Dx);
221
222
223 if (iscylinder) {
224 Handle (Geom_CylindricalSurface)
225 gcyl = new Geom_CylindricalSurface( ChamfAx3, ChamfRad );
226
227 // changes due to the fact the parameters of the chamfer must go increasing
228 // from surface S1 to surface S2
229 if (!plandab) {
230 gcyl->VReverse();// be carefull : the SemiAngle was changed
231 ChamfAx3 = gcyl->Position();
232 }
233
234 // changes due to the fact we have reversed the V direction of
235 // parametrization
236 if (ChamfAx3.YDirection().Dot(DSp) <= 0.) {
237 ChamfAx3.YReverse();
238 gcyl->SetPosition(ChamfAx3);
239 }
240
241 Data->ChangeSurf(ChFiKPart_IndexSurfaceInDS(gcyl,DStr));
242
243 Standard_Boolean torevcha = !ChamfAx3.Direct();
244 gp_Dir cylaxe = (ChamfAx3.Axis()).Direction();
245 torevcha = ( (torevcha && !plandab) || (!torevcha && plandab));
246
247 if (torevcha) cylaxe.Reverse();
248 Standard_Boolean toreverse = (norf.Dot(cylaxe) < 0.);
249
250 if ((toreverse && dedans) || (!toreverse && !dedans))
251 Data->ChangeOrientation() = TopAbs_REVERSED;
252 else
253 Data->ChangeOrientation() = TopAbs_FORWARD;
254
255 //we load the faceInterference with the pcurves and
256 // the 3d curves
257
258 // Case of the plane face
259 // NB: in the case 'pointu', no pcurve on the plane surface
260 // and no intersection plane-chamfer are needed
261
262 // intersection plane-chamfer
263 Handle(Geom_Circle) GCirPln;
264 Handle(Geom2d_Circle) GCir2dPln;
265 gp_Ax2 CirAx2 = ChamfAx3.Ax2();
266 CirAx2.SetLocation(PtPl);
267
268 Pt.SetCoord(PtPl.X()+ChamfRad*Dx.X(),
269 PtPl.Y()+ChamfRad*Dx.Y(),
270 PtPl.Z()+ChamfRad*Dx.Z());
271 gp_Circ CirPln(CirAx2,ChamfRad);
272 GCirPln = new Geom_Circle(CirPln);
273
274 //pcurve on the plane
275 ElSLib::PlaneParameters(PosPl,Pt ,u,v);
276 gp_Pnt2d p2dPln(u,v);
277 gp_Dir2d d2d(DSp.Dot(PosPl.XDirection()),DSp.Dot(PosPl.YDirection()));
278 gp_Ax22d ax2dPln(pt2dPln, gp_Dir2d(gp_Vec2d(pt2dPln,p2dPln)),d2d);
279 gp_Circ2d cir2dPln(ax2dPln,ChamfRad);
280 GCir2dPln = new Geom2d_Circle(cir2dPln);
281
282 //pcurve on chamfer
283 gp_Pnt2d p2dch;
284 p2dch.SetCoord(0.,0.);
285 // ElSLib::CylinderD1(0.,0.,ChamfAx3,ChamfRad,Pt,deru,derv);
286 gp_Lin2d lin2dch(p2dch,gp::DX2d());
287 Handle(Geom2d_Line) GLin2dCh1 = new Geom2d_Line(lin2dch);
288
289 //orientation
290 TopAbs_Orientation trans;
291 gp_Dir norpl = PosPl.XDirection().Crossed(PosPl.YDirection());
292 toreverse = (norpl.Dot(cylaxe) < 0.);
293
294 toreverse = (toreverse && plandab) || (!toreverse && !plandab);
295
296 if ((toreverse && dedans) || (!toreverse && !dedans)) {
297 trans = TopAbs_FORWARD;
298 }
299 else {
300 trans = TopAbs_REVERSED;
301 }
302
303 if (plandab) {
304 Data->ChangeInterferenceOnS1().
305 SetInterference(ChFiKPart_IndexCurveInDS(GCirPln,DStr),
306 trans,GCir2dPln,GLin2dCh1);
307 }
308 else {
309 Data->ChangeInterferenceOnS2().
310 SetInterference(ChFiKPart_IndexCurveInDS(GCirPln,DStr),
311 trans,GCir2dPln,GLin2dCh1);
312 }
313
314 // Case of the conical face
315
316 //intersection cone-chamfer
317 Standard_Real Rad;
318 if (dedans)
319 Rad = ChamfRad + dis;
320 else
321 Rad = ChamfRad - dis;
322
323 CirAx2.SetLocation(Or);
324 gp_Circ CirCon(CirAx2, Rad);
325 Handle(Geom_Circle) GCirCon = new Geom_Circle(CirCon);
326
327 //pcurve on chamfer
328 if (plandab)
329 v = sqrt(dis*dis + move*move);
330 else
331 v = - sqrt(dis*dis + move*move);
332 p2dch.SetCoord(0.,v);
333 ElSLib::CylinderD1(0.,v,ChamfAx3,ChamfRad,Pt,deru,derv);
334 lin2dch.SetLocation(p2dch);
335 Handle(Geom2d_Line) GLin2dCh2 = new Geom2d_Line(lin2dch);
336
337 //pcurve on cone
338 Pt.SetCoord(Or.X()+Rad*Dx.X(),
339 Or.Y()+Rad*Dx.Y(),
340 Or.Z()+Rad*Dx.Z());
341 ElSLib::Parameters(Con,Pt ,u,v);
342 Standard_Real tol = Precision::PConfusion();
c6541a0c 343 if(u >= 2*M_PI - tol && u <= 2*M_PI) u = 0.;
7fd59977 344 if(u >= fu - tol && u < fu) u = fu;
345 if(u <= lu + tol && u > lu) u = lu;
c6541a0c 346 if(u < fu || u > lu) u = ElCLib::InPeriod(u,fu,fu + 2*M_PI);
7fd59977 347 ElSLib::D1(u,v,Con,Pt,deru,derv);
348 gp_Pnt2d p2dCon(u,v);
349 gp_Dir2d d2dCon;
350 if ( deru.Dot(DSp)<=0. )
351 d2dCon = - gp::DX2d();
352 else
353 d2dCon = gp::DX2d();
354 gp_Lin2d lin2dCon(p2dCon,d2dCon);
355 Handle(Geom2d_Line) GLin2dCon = new Geom2d_Line(lin2dCon);
356
357 //orientation
358 gp_Dir norcon = deru.Crossed(derv);
359
360 gp_Dir DirCon = (Con.Axis()).Direction();
361 if (angCon > Precision::Confusion()) DirCon.Reverse();
362 Standard_Boolean torevcon = ( norcon.Dot(DirCon) < 0. );
363
364 if ((torevcon && dedans) || (!torevcon && !dedans) ) {
365 trans = TopAbs_REVERSED;
366 }
367 else {
368 trans = TopAbs_FORWARD;
369 }
370
371 if(plandab){
372 Data->ChangeInterferenceOnS2().
373 SetInterference(ChFiKPart_IndexCurveInDS(GCirCon,DStr),
374 trans,GLin2dCon,GLin2dCh2);
375 }
376 else {
377 Data->ChangeInterferenceOnS1().
378 SetInterference(ChFiKPart_IndexCurveInDS(GCirCon,DStr),
379 trans,GLin2dCon,GLin2dCh2);
380 }
381 }
382 else {
383 Handle (Geom_ConicalSurface)
384 gcon = new Geom_ConicalSurface( ChamfAx3, SemiAngl, ChamfRad );
385
386 // changes due to the fact the parameters of the chamfer must go increasing
387 // from surface S1 to surface S2
388 if (!plandab) {
389 gcon->VReverse();// be carefull : the SemiAngle was changed
390 ChamfAx3 = gcon->Position();
391 SemiAngl = gcon->SemiAngle();
392 }
393
394 // changes due to the fact we have reversed the V direction of
395 // parametrization
396 if (ChamfAx3.YDirection().Dot(DSp) <= 0.) {
397 ChamfAx3.YReverse();
398 gcon->SetPosition(ChamfAx3);
399 }
400
401 Data->ChangeSurf(ChFiKPart_IndexSurfaceInDS(gcon,DStr));
402
403 //compute the chamfer's orientation according to the orientation
404 // of the faces
405
406 //search the normal to the conical chamfer
407 gp_Pnt P;
408 u = 0.;
409 if (plandab)
410 v = sqrt(dis*dis + move*move);
411 else
412 v = - sqrt(dis*dis + move*move);
413
414 ElSLib::ConeD1(u,v,ChamfAx3,ChamfRad,SemiAngl,P,deru,derv);
415 gp_Dir norchamf(deru.Crossed(derv));
416
417 Standard_Boolean toreverse = (norf.Dot(norchamf) < 0.);
418
419 if (isConPar) toreverse = !toreverse;
420
421 if (toreverse)
422 Data->ChangeOrientation() = TopAbs_REVERSED;
423 else
424 Data->ChangeOrientation() = TopAbs_FORWARD;
425
426 //we load the faceInterference with the pcurves and
427 // the 3d curves
428
429 // Case of the plane face
430 // NB: in the case 'pointu', no pcurve on the plane surface
431 // and no intersection plane-chamfer are needed
432
433 // intersection plane-chamfer
434 Handle(Geom_Circle) GCirPln;
435 Handle(Geom2d_Circle) GCir2dPln;
436 gp_Ax2 CirAx2 = ChamfAx3.Ax2();
437 CirAx2.SetLocation(PtPl);
438
439 if (!pointu) {
440 Pt.SetCoord(PtPl.X()+ChamfRad*Dx.X(),
441 PtPl.Y()+ChamfRad*Dx.Y(),
442 PtPl.Z()+ChamfRad*Dx.Z());
443 gp_Circ CirPln(CirAx2,ChamfRad);
444 GCirPln = new Geom_Circle(CirPln);
445
446 //pcurve on the plane
447 ElSLib::PlaneParameters(PosPl,Pt ,u,v);
448 gp_Pnt2d p2dPln(u,v);
449 gp_Dir2d d2d(DSp.Dot(PosPl.XDirection()),DSp.Dot(PosPl.YDirection()));
450 gp_Ax22d ax2dPln(pt2dPln, gp_Dir2d(gp_Vec2d(pt2dPln,p2dPln)),d2d);
451 gp_Circ2d cir2dPln(ax2dPln,ChamfRad);
452 GCir2dPln = new Geom2d_Circle(cir2dPln);
453 }
454
455 //pcurve on chamfer
456 gp_Pnt2d p2dch;
457 p2dch.SetCoord(0.,0.);
458 ElSLib::ConeD1(0.,0.,ChamfAx3,ChamfRad,SemiAngl,Pt,deru,derv);
459 gp_Lin2d lin2dch(p2dch,gp::DX2d());
460 Handle(Geom2d_Line) GLin2dCh1 = new Geom2d_Line(lin2dch);
461
462 //orientation
463 TopAbs_Orientation trans;
464 gp_Dir norpl = PosPl.XDirection().Crossed(PosPl.YDirection());
465 if (!pointu)
466 norchamf.SetXYZ (deru.Crossed(derv).XYZ());
467 toreverse = ( norchamf.Dot(norpl) <= 0. );
468
469 if (isConPar) toreverse = !toreverse;
470
471 if ((toreverse && plandab) || (!toreverse && !plandab)){
472 trans = TopAbs_FORWARD;
473 }
474 else {
475 trans = TopAbs_REVERSED;
476 }
477
478 if (plandab) {
479 Data->ChangeInterferenceOnS1().
480 SetInterference(ChFiKPart_IndexCurveInDS(GCirPln,DStr),
481 trans,GCir2dPln,GLin2dCh1);
482 }
483 else {
484 Data->ChangeInterferenceOnS2().
485 SetInterference(ChFiKPart_IndexCurveInDS(GCirPln,DStr),
486 trans,GCir2dPln,GLin2dCh1);
487 }
488
489 // Case of the conical face
490
491 //intersection cone-chamfer
492 Standard_Real Rad;
493 if (dedans)
494 Rad = ChamfRad + dis;
495 else
496 Rad = ChamfRad - dis;
497
498 CirAx2.SetLocation(Or);
499 gp_Circ CirCon(CirAx2, Rad);
500 Handle(Geom_Circle) GCirCon = new Geom_Circle(CirCon);
501
502 //pcurve on chamfer
503 if (plandab)
504 v = sqrt(dis*dis + move*move);
505 else
506 v = - sqrt(dis*dis + move*move);
507 p2dch.SetCoord(0.,v);
508 ElSLib::ConeD1(0.,v,ChamfAx3,ChamfRad,SemiAngl,Pt,deru,derv);
509 lin2dch.SetLocation(p2dch);
510 Handle(Geom2d_Line) GLin2dCh2 = new Geom2d_Line(lin2dch);
511
512 //pcurve on cone
513 norchamf.SetXYZ (deru.Crossed(derv).XYZ());
514
515 Pt.SetCoord(Or.X()+Rad*Dx.X(),
516 Or.Y()+Rad*Dx.Y(),
517 Or.Z()+Rad*Dx.Z());
518 ElSLib::Parameters(Con,Pt ,u,v);
519 Standard_Real tol = Precision::PConfusion();
c6541a0c 520 if (u >= 2*M_PI - tol && u <= 2*M_PI) u = 0.;
7fd59977 521 if (u >= fu - tol && u < fu) u = fu;
522 if (u <= lu + tol && u > lu) u = lu;
c6541a0c 523 if (u < fu || u > lu) u = ElCLib::InPeriod(u,fu,fu + 2*M_PI);
7fd59977 524 ElSLib::D1(u,v,Con,Pt,deru,derv);
525 gp_Pnt2d p2dCon(u,v);
526 gp_Dir2d d2dCon;
527 if ( deru.Dot(DSp)<=0. )
528 d2dCon = - gp::DX2d();
529 else
530 d2dCon = gp::DX2d();
531 gp_Lin2d lin2dCon(p2dCon,d2dCon);
532 Handle(Geom2d_Line) GLin2dCon = new Geom2d_Line(lin2dCon);
533
534 //orientation
535 gp_Dir norcon = deru.Crossed(derv);
536
537 gp_Dir DirCon = (Con.Axis()).Direction();
538 gp_Dir DirChamf = (gcon->Axis()).Direction();
539 if (angCon > Precision::Confusion()) DirCon.Reverse();
540 if (SemiAngl > Precision::Confusion()) DirChamf.Reverse();
541
542 Standard_Boolean torevcon = ( norcon.Dot(DirCon) > 0. );
543 Standard_Boolean torevcha = ( norchamf.Dot(DirChamf) > 0. );
544
545 toreverse = ( (torevcon && !torevcha) || (!torevcon && torevcha) );
546
547 if ((toreverse && plandab) || (!toreverse && !plandab) ) {
548 trans = TopAbs_REVERSED;
549 }
550 else {
551 trans = TopAbs_FORWARD;
552 }
553
554 if(plandab){
555 Data->ChangeInterferenceOnS2().
556 SetInterference(ChFiKPart_IndexCurveInDS(GCirCon,DStr),
557 trans,GLin2dCon,GLin2dCh2);
558 }
559 else {
560 Data->ChangeInterferenceOnS1().
561 SetInterference(ChFiKPart_IndexCurveInDS(GCirCon,DStr),
562 trans,GLin2dCon,GLin2dCh2);
563 }
564
565 }
566 return Standard_True;
567}
568
569
570
571