0024023: Revamp the OCCT Handle -- ambiguity
[occt.git] / src / Extrema / Extrema_ExtElCS.cxx
CommitLineData
b311480e 1// Copyright (c) 1995-1999 Matra Datavision
973c2be1 2// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
b311480e 5//
d5f74e42 6// This library is free software; you can redistribute it and/or modify it under
7// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
b311480e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
7fd59977 14
15// Modified by skv - Thu Jul 7 14:37:05 2005 OCC9134
16
17#include <Extrema_ExtElCS.ixx>
18#include <Extrema_ExtPElS.hxx>
19#include <Extrema_ExtPElC.hxx>
20#include <Extrema_ExtElC.hxx>
21#include <Extrema_POnCurv.hxx>
22#include <Standard_NotImplemented.hxx>
23#include <StdFail_InfiniteSolutions.hxx>
24#include <Precision.hxx>
25#include <ElSLib.hxx>
26#include <ElCLib.hxx>
27#include <gp_Vec.hxx>
f34cd0d1 28#include <IntAna_Quadric.hxx>
29#include <IntAna_IntConicQuad.hxx>
7fd59977 30
31
32Extrema_ExtElCS::Extrema_ExtElCS()
33{
34 myDone = Standard_False;
35 myIsPar = Standard_False;
36}
37
38
39Extrema_ExtElCS::Extrema_ExtElCS(const gp_Lin& C,
40 const gp_Pln& S)
41{
42 Perform(C, S);
43}
44
45
46
47void Extrema_ExtElCS::Perform(const gp_Lin& C,
48 const gp_Pln& S)
49{
50 myDone = Standard_True;
51 myIsPar = Standard_False;
52
53 if (C.Direction().IsNormal(S.Axis().Direction(),
54 Precision::Angular())) {
55 mySqDist = new TColStd_HArray1OfReal(1, 1);
56 mySqDist->SetValue(1, S.SquareDistance(C));
57 myIsPar = Standard_True;
58 }
59 else {
60 myNbExt = 0;
61 }
62
63}
64
65
66Extrema_ExtElCS::Extrema_ExtElCS(const gp_Lin& C,
67 const gp_Cylinder& S)
68{
69 Perform(C, S);
70}
71
72
73
74void Extrema_ExtElCS::Perform(const gp_Lin& C,
db914841 75 const gp_Cylinder& S)
7fd59977 76{
77 myDone = Standard_False;
78 myNbExt = 0;
79 myIsPar = Standard_False;
80
81 gp_Ax3 Pos = S.Position();
f34cd0d1 82 gp_Pnt Origin = Pos.Location();
83 gp_Pnt LineOrig = C.Location();
84
7fd59977 85 Standard_Real radius = S.Radius();
86 Extrema_ExtElC Extrem(gp_Lin(Pos.Axis()), C, Precision::Angular());
87 if (Extrem.IsParallel()) {
db914841 88 // Line direction is similar to cylinder axis of rotation.
7fd59977 89 mySqDist = new TColStd_HArray1OfReal(1, 1);
f34cd0d1 90 myPoint1 = new Extrema_HArray1OfPOnCurv(1, 1);
91 myPoint2 = new Extrema_HArray1OfPOnSurf(1, 1);
92 Standard_Real aDist = sqrt(Extrem.SquareDistance(1)) - radius;
7fd59977 93 mySqDist->SetValue(1, aDist * aDist);
f34cd0d1 94 Standard_Real u, v, w;
95 gp_Vec aVec(LineOrig, Origin);
96 gp_Vec aDirVec(C.Direction());
97 w = aVec*aDirVec;
98 gp_Pnt LinPoint = LineOrig.Translated(w * aDirVec);
99 Extrema_POnCurv PonC(w, LinPoint);
100 myPoint1->SetValue(1, PonC);
101 gp_Pnt CylPoint;
102 gp_Vec OrigToLine(Origin, LinPoint);
103 if (OrigToLine.Magnitude() <= gp::Resolution())
104 {
105 u = 0.;
106 v = 0.;
107 CylPoint = ElSLib::Value(u, v, S);
108 }
109 else
110 {
111 OrigToLine.Normalize();
112 CylPoint = Origin.Translated(radius * OrigToLine);
113 ElSLib::CylinderParameters(Pos, radius, CylPoint, u, v);
114 }
115 Extrema_POnSurf PonS(u, v, CylPoint);
116 myPoint2->SetValue(1, PonS);
7fd59977 117 myDone = Standard_True;
118 myIsPar = Standard_True;
119 }
120 else {
db914841 121 Standard_Integer i, aStartIdx = 0;
122
f34cd0d1 123 Extrema_POnCurv myPOnC1, myPOnC2;
124 Extrem.Points(1, myPOnC1, myPOnC2);
125 gp_Pnt PonAxis = myPOnC1.Value();
126 gp_Pnt PC = myPOnC2.Value();
127
f34cd0d1 128 // line intersects the cylinder
db914841 129 if (radius - PonAxis.Distance(PC) > Precision::PConfusion())
f34cd0d1 130 {
131 IntAna_Quadric theQuadric(S);
132 IntAna_IntConicQuad Inters(C, theQuadric);
133 if (Inters.IsDone())
134 {
135 myNbExt = Inters.NbPoints();
db914841 136 aStartIdx = myNbExt;
f34cd0d1 137 if (myNbExt > 0)
138 {
db914841 139 // Not more than 2 additional points from perpendiculars.
140 mySqDist = new TColStd_HArray1OfReal(1, myNbExt + 2);
141 myPoint1 = new Extrema_HArray1OfPOnCurv(1, myNbExt + 2);
142 myPoint2 = new Extrema_HArray1OfPOnSurf(1, myNbExt + 2);
f34cd0d1 143 Standard_Real u, v, w;
144 for (i = 1; i <= myNbExt; i++)
145 {
146 mySqDist->SetValue(i, 0.);
147 gp_Pnt P_int = Inters.Point(i);
148 w = Inters.ParamOnConic(i);
149 Extrema_POnCurv PonC(w, P_int);
150 myPoint1->SetValue(i, PonC);
151 ElSLib::CylinderParameters(Pos, radius, P_int, u, v);
152 Extrema_POnSurf PonS(u, v, P_int);
153 myPoint2->SetValue(i, PonS);
154 }
155 }
7fd59977 156 }
7fd59977 157 }
db914841 158
159 // line is tangent or outside of the cylinder
160 Extrema_ExtPElS ExPS(PC, S, Precision::Confusion());
161 if (ExPS.IsDone())
162 {
163 if (aStartIdx == 0)
164 {
165 myNbExt = ExPS.NbExt();
166 mySqDist = new TColStd_HArray1OfReal(1, myNbExt);
167 myPoint1 = new Extrema_HArray1OfPOnCurv(1, myNbExt);
168 myPoint2 = new Extrema_HArray1OfPOnSurf(1, myNbExt);
169 }
170 else
171 myNbExt += ExPS.NbExt();
172
173 for (i = aStartIdx + 1; i <= myNbExt; i++) {
174 myPoint1->SetValue(i, myPOnC2);
175 myPoint2->SetValue(i, ExPS.Point(i - aStartIdx));
176 mySqDist->SetValue(i,(myPOnC2.Value()).SquareDistance(ExPS.Point(i - aStartIdx).Value()));
177 }
178 }
f34cd0d1 179 myDone = Standard_True;
7fd59977 180 }
181
182}
183
184
185
186Extrema_ExtElCS::Extrema_ExtElCS(const gp_Lin& C,
187 const gp_Cone& S)
188{
189 Perform(C, S);
190}
191
192
193
194//void Extrema_ExtElCS::Perform(const gp_Lin& C,
195// const gp_Cone& S)
196void Extrema_ExtElCS::Perform(const gp_Lin& ,
197 const gp_Cone& )
198{
199 Standard_NotImplemented::Raise();
200
201}
202
203
204
205Extrema_ExtElCS::Extrema_ExtElCS(const gp_Lin& C,
206 const gp_Sphere& S)
207{
208 Perform(C, S);
209}
210
211
212
213void Extrema_ExtElCS::Perform(const gp_Lin& C,
db914841 214 const gp_Sphere& S)
7fd59977 215{
db914841 216 // In case of intersection - return four points:
217 // 2 intersection points and 2 perpendicular.
218 // No intersection - only min and max.
219
7fd59977 220 myDone = Standard_False;
221 myNbExt = 0;
222 myIsPar = Standard_False;
db914841 223 Standard_Integer aStartIdx = 0;
7fd59977 224
db914841 225 gp_Pnt aCenter = S.Location();
7fd59977 226
db914841 227 Extrema_ExtPElC Extrem(aCenter, C, Precision::Angular(), RealFirst(), RealLast());
7fd59977 228
229 Standard_Integer i;
db914841 230 if (Extrem.IsDone() &&
231 Extrem.NbExt() > 0)
232 {
7fd59977 233 Extrema_POnCurv myPOnC1 = Extrem.Point(1);
db914841 234 if (myPOnC1.Value().Distance(aCenter) <= S.Radius())
235 {
236 IntAna_IntConicQuad aLinSphere(C, S);
237 if (aLinSphere.IsDone())
238 {
239 myNbExt = aLinSphere.NbPoints();
240 aStartIdx = myNbExt;
241 // Not more than 2 additional points from perpendiculars.
242 mySqDist = new TColStd_HArray1OfReal(1, myNbExt + 2);
243 myPoint1 = new Extrema_HArray1OfPOnCurv(1, myNbExt + 2);
244 myPoint2 = new Extrema_HArray1OfPOnSurf(1, myNbExt + 2);
245
246 for (i = 1; i <= myNbExt; i++)
247 {
248 Extrema_POnCurv aCPnt(aLinSphere.ParamOnConic(i), aLinSphere.Point(i));
249
250 Standard_Real u,v;
251 ElSLib::Parameters(S, aLinSphere.Point(i), u, v);
252 Extrema_POnSurf aSPnt(u, v, aLinSphere.Point(i));
253
254 myPoint1->SetValue(i, aCPnt);
255 myPoint2->SetValue(i, aSPnt);
256 mySqDist->SetValue(i,(aCPnt.Value()).SquareDistance(aSPnt.Value()));
257 }
258 }
259 }
260
7fd59977 261 Extrema_ExtPElS ExPS(myPOnC1.Value(), S, Precision::Confusion());
db914841 262 if (ExPS.IsDone())
263 {
264 if (aStartIdx == 0)
265 {
266 myNbExt = ExPS.NbExt();
267 mySqDist = new TColStd_HArray1OfReal(1, myNbExt);
268 myPoint1 = new Extrema_HArray1OfPOnCurv(1, myNbExt);
269 myPoint2 = new Extrema_HArray1OfPOnSurf(1, myNbExt);
270 }
271 else
272 myNbExt += ExPS.NbExt();
273
274 for (i = aStartIdx + 1; i <= myNbExt; i++)
275 {
276 myPoint1->SetValue(i, myPOnC1);
277 myPoint2->SetValue(i, ExPS.Point(i - aStartIdx));
278 mySqDist->SetValue(i,(myPOnC1.Value()).SquareDistance(ExPS.Point(i - aStartIdx).Value()));
7fd59977 279 }
280 }
281 }
db914841 282 myDone = Standard_True;
7fd59977 283}
284
285
286Extrema_ExtElCS::Extrema_ExtElCS(const gp_Lin& C,
287 const gp_Torus& S)
288{
289 Perform(C, S);
290}
291
292
293
294//void Extrema_ExtElCS::Perform(const gp_Lin& C,
295// const gp_Torus& S)
296void Extrema_ExtElCS::Perform(const gp_Lin& ,
297 const gp_Torus& )
298{
299 Standard_NotImplemented::Raise();
300
301}
302
303
304// Circle-?
305
306Extrema_ExtElCS::Extrema_ExtElCS(const gp_Circ& C,
307 const gp_Pln& S)
308{
309 Perform(C, S);
310}
311
312
313
9dfbbfe6 314void Extrema_ExtElCS::Perform(const gp_Circ& C,
315 const gp_Pln& S)
7fd59977 316{
9dfbbfe6 317 myDone = Standard_True;
318 myIsPar = Standard_False;
319
320 gp_Ax2 Pos = C.Position();
321 gp_Dir NCirc = Pos.Direction();
322 gp_Dir NPln = S.Axis().Direction();
323
324 if (NCirc.IsParallel(NPln, Precision::Angular())) {
325
326 mySqDist = new TColStd_HArray1OfReal(1, 1);
327 mySqDist->SetValue(1, S.SquareDistance(C.Location()));
328 myIsPar = Standard_True;
329
330 }
331 else {
332
333 gp_Dir ExtLine = NCirc ^ NPln;
334 ExtLine = ExtLine ^ NCirc;
335 //
336 gp_Dir XDir = Pos.XDirection();
337 Standard_Real T[2];
338 T[0] = XDir.AngleWithRef(ExtLine, NCirc);
339 if(T[0] < 0.)
340 {
341 //Put in period
342 T[0] += M_PI;
343 }
344 T[1] = T[0] + M_PI;
345 //
346 myNbExt = 2;
347 //Check intersection
348 IntAna_IntConicQuad anInter(C, S,
349 Precision::Angular(),
350 Precision::Confusion());
351 if(anInter.IsDone())
352 {
353 if(anInter.NbPoints() > 1)
354 {
355 myNbExt += anInter.NbPoints();
356 }
357 }
358
359 myPoint1 = new Extrema_HArray1OfPOnCurv(1, myNbExt);
360 mySqDist = new TColStd_HArray1OfReal(1, myNbExt);
361 myPoint2 = new Extrema_HArray1OfPOnSurf(1, myNbExt);
7fd59977 362
9dfbbfe6 363 Standard_Integer i;
364 gp_Pnt PC, PP;
365 Standard_Real U, V;
366 Extrema_POnCurv POnC;
367 Extrema_POnSurf POnS;
368 for(i = 0; i < 2; ++i)
369 {
370 PC = ElCLib::CircleValue(T[i], C.Position(), C.Radius());
371 POnC.SetValues(T[i], PC);
372 myPoint1->SetValue(i+1, POnC);
373 ElSLib::PlaneParameters(S.Position(), PC, U, V);
374 PP = ElSLib::PlaneValue(U, V, S.Position());
375 POnS.SetParameters(U, V, PP);
376 myPoint2->SetValue(i+1, POnS);
377 mySqDist->SetValue(i+1, PC.SquareDistance(PP));
378 }
379 //
380 if(myNbExt > 2)
381 {
382 //Add intersection points
383 for(i = 1; i <= anInter.NbPoints(); ++i)
384 {
385 Standard_Real t = anInter.ParamOnConic(i);
386 PC = ElCLib::CircleValue(t, C.Position(), C.Radius());
387 POnC.SetValues(t, PC);
388 myPoint1->SetValue(i+2, POnC);
389 ElSLib::PlaneParameters(S.Position(), PC, U, V);
390 PP = ElSLib::PlaneValue(U, V, S.Position());
391 POnS.SetParameters(U, V, PP);
392 myPoint2->SetValue(i+2, POnS);
393 mySqDist->SetValue(i+2, PC.SquareDistance(PP));
394 }
395 }
396 }
397 //
7fd59977 398}
399
400
401
402Extrema_ExtElCS::Extrema_ExtElCS(const gp_Circ& C,
403 const gp_Cylinder& S)
404{
405 Perform(C, S);
406}
407
408
409
410// Modified by skv - Thu Jul 7 14:37:05 2005 OCC9134 Begin
411// Implementation of the method.
412void Extrema_ExtElCS::Perform(const gp_Circ& C,
413 const gp_Cylinder& S)
414{
415 myDone = Standard_False;
416 myIsPar = Standard_False;
417 myNbExt = 0;
418
419 // Get an axis line of the cylinder.
420 gp_Lin anAxis(S.Axis());
421
422 // Compute extrema between the circle and the line.
423 Extrema_ExtElC anExtC(anAxis, C, 0.);
424
425 if (anExtC.IsDone()) {
426 if (anExtC.IsParallel()) {
427 myIsPar = Standard_True;
428 mySqDist = new TColStd_HArray1OfReal(1, 1);
429 Standard_Real aDist = sqrt (anExtC.SquareDistance(1)) - S.Radius();
430 mySqDist->SetValue(1, aDist * aDist);
431 } else {
432 Standard_Integer aNbExt = anExtC.NbExt();
7fd59977 433 Standard_Integer i;
434 Standard_Integer aCurI = 1;
435 Standard_Real aTolConf = Precision::Confusion();
436 Standard_Real aCylRad = S.Radius();
437
19875353 438 // Check whether two objects have intersection points
439 IntAna_Quadric aCylQuad(S);
440 IntAna_IntConicQuad aCircCylInter(C, aCylQuad);
fc0180e5 441 Standard_Integer aNbInter = 0;
442 if (aCircCylInter.IsDone())
443 aNbInter = aCircCylInter.NbPoints();
19875353 444
7fd59977 445 // Compute the extremas.
19875353 446 myNbExt = 2*aNbExt + aNbInter;
7fd59977 447 mySqDist = new TColStd_HArray1OfReal(1, myNbExt);
448 myPoint1 = new Extrema_HArray1OfPOnCurv(1, myNbExt);
449 myPoint2 = new Extrema_HArray1OfPOnSurf(1, myNbExt);
450
451 for (i = 1; i <= aNbExt; i++) {
19875353 452 Extrema_POnCurv aPOnAxis;
453 Extrema_POnCurv aPOnCirc;
454 Standard_Real aSqDist = anExtC.SquareDistance(i);
455 Standard_Real aDist = sqrt (aSqDist);
456
457 anExtC.Points(i, aPOnAxis, aPOnCirc);
458
459 if (aSqDist <= (aTolConf * aTolConf)) {
460 myNbExt -= 2;
461 continue;
462 }
463
464 gp_Dir aDir(aPOnAxis.Value().XYZ().Subtracted(aPOnCirc.Value().XYZ()));
465 Standard_Real aShift[2] = { aDist + aCylRad, aDist - aCylRad };
466 Standard_Integer j;
7fd59977 467
19875353 468 for (j = 0; j < 2; j++) {
469 gp_Vec aVec(aDir);
470 gp_Pnt aPntOnCyl;
7fd59977 471
19875353 472 aVec.Multiply(aShift[j]);
473 aPntOnCyl = aPOnCirc.Value().Translated(aVec);
7fd59977 474
19875353 475 Standard_Real aU;
476 Standard_Real aV;
7fd59977 477
19875353 478 ElSLib::Parameters(S, aPntOnCyl, aU, aV);
7fd59977 479
19875353 480 Extrema_POnSurf aPOnSurf(aU, aV, aPntOnCyl);
7fd59977 481
19875353 482 myPoint1->SetValue(aCurI, aPOnCirc);
483 myPoint2->SetValue(aCurI, aPOnSurf);
484 mySqDist->SetValue(aCurI++, aShift[j] * aShift[j]);
485 }
486 }
487
488 // Adding intersection points to the list of extremas
489 for (i=1; i<=aNbInter; i++)
490 {
491 Standard_Real aU;
492 Standard_Real aV;
7fd59977 493
19875353 494 gp_Pnt aInterPnt = aCircCylInter.Point(i);
7fd59977 495
19875353 496 aU = ElCLib::Parameter(C, aInterPnt);
497 Extrema_POnCurv aPOnCirc(aU, aInterPnt);
7fd59977 498
19875353 499 ElSLib::Parameters(S, aInterPnt, aU, aV);
500 Extrema_POnSurf aPOnCyl(aU, aV, aInterPnt);
501 myPoint1->SetValue(aCurI, aPOnCirc);
502 myPoint2->SetValue(aCurI, aPOnCyl);
503 mySqDist->SetValue(aCurI++, 0.0);
7fd59977 504 }
505 }
506
507 myDone = Standard_True;
508 }
509}
510// Modified by skv - Thu Jul 7 14:37:05 2005 OCC9134 End
511
512
513
514Extrema_ExtElCS::Extrema_ExtElCS(const gp_Circ& C,
515 const gp_Cone& S)
516{
517 Perform(C, S);
518}
519
520
521
522//void Extrema_ExtElCS::Perform(const gp_Circ& C,
523// const gp_Cone& S)
524void Extrema_ExtElCS::Perform(const gp_Circ& ,
525 const gp_Cone& )
526{
527 Standard_NotImplemented::Raise();
528
529}
530
531
532
533Extrema_ExtElCS::Extrema_ExtElCS(const gp_Circ& C,
534 const gp_Sphere& S)
535{
536 Perform(C, S);
537}
538
539
540
541//void Extrema_ExtElCS::Perform(const gp_Circ& C,
542// const gp_Sphere& S)
543void Extrema_ExtElCS::Perform(const gp_Circ& ,
544 const gp_Sphere& )
545{
546 Standard_NotImplemented::Raise();
547
548}
549
550Extrema_ExtElCS::Extrema_ExtElCS(const gp_Circ& C,
551 const gp_Torus& S)
552{
553 Perform(C, S);
554}
555
556
557
558//void Extrema_ExtElCS::Perform(const gp_Circ& C,
559// const gp_Torus& S)
560void Extrema_ExtElCS::Perform(const gp_Circ& ,
561 const gp_Torus& )
562{
563 Standard_NotImplemented::Raise();
564
565}
566
567Extrema_ExtElCS::Extrema_ExtElCS(const gp_Hypr& C,
568 const gp_Pln& S)
569{
570 Perform(C, S);
571}
572
573
574
575void Extrema_ExtElCS::Perform(const gp_Hypr& C,
576 const gp_Pln& S)
577{
578 myDone = Standard_True;
579 myIsPar = Standard_False;
580
581 gp_Ax2 Pos = C.Position();
582 gp_Dir NHypr = Pos.Direction();
583 gp_Dir NPln = S.Axis().Direction();
584
585 if (NHypr.IsParallel(NPln, Precision::Angular())) {
586
587 mySqDist = new TColStd_HArray1OfReal(1, 1);
588 mySqDist->SetValue(1, S.SquareDistance(C.Location()));
589 myIsPar = Standard_True;
590
591 }
592 else {
593
594 gp_Dir XDir = Pos.XDirection();
595 gp_Dir YDir = Pos.YDirection();
596
597 Standard_Real A = C.MinorRadius()*(NPln.Dot(YDir));
598 Standard_Real B = C.MajorRadius()*(NPln.Dot(XDir));
599
600 if(Abs(B) > Abs(A)) {
601 Standard_Real T = -0.5 * Log((A+B)/(B-A));
602 gp_Pnt Ph = ElCLib::HyperbolaValue(T, Pos, C.MajorRadius(), C.MinorRadius());
603 Extrema_POnCurv PC(T, Ph);
604 myPoint1 = new Extrema_HArray1OfPOnCurv(1,1);
605 myPoint1->SetValue(1, PC);
606
607 mySqDist = new TColStd_HArray1OfReal(1, 1);
608 mySqDist->SetValue(1, S.SquareDistance(Ph));
609
610 Standard_Real U, V;
611 ElSLib::PlaneParameters(S.Position(), Ph, U, V);
612 gp_Pnt Pp = ElSLib::PlaneValue(U, V, S.Position());
613 Extrema_POnSurf PS(U, V, Pp);
614 myPoint2 = new Extrema_HArray1OfPOnSurf(1,1);
615 myPoint2->SetValue(1, PS);
616
617 myNbExt = 1;
618 }
619 else {
620 myNbExt = 0;
621 }
622
623 }
624
625}
626
627
628Standard_Boolean Extrema_ExtElCS::IsDone() const
629{
630 return myDone;
631}
632
633
634Standard_Integer Extrema_ExtElCS::NbExt() const
635{
636 if (myIsPar) StdFail_InfiniteSolutions::Raise();
637 return myNbExt;
638}
639
640Standard_Real Extrema_ExtElCS::SquareDistance(const Standard_Integer N) const
641{
642 if (myIsPar && N != 1) StdFail_InfiniteSolutions::Raise();
643 return mySqDist->Value(N);
644}
645
646
647void Extrema_ExtElCS::Points(const Standard_Integer N,
648 Extrema_POnCurv& P1,
649 Extrema_POnSurf& P2) const
650{
651 if (myIsPar) StdFail_InfiniteSolutions::Raise();
652 P1 = myPoint1->Value(N);
653 P2 = myPoint2->Value(N);
654}
655
656
657Standard_Boolean Extrema_ExtElCS::IsParallel() const
658{
659 return myIsPar;
660}