0031459: Visualization, AIS_TextLabel - add missing getters
[occt.git] / src / AIS / AIS_MidPointRelation.cxx
CommitLineData
b311480e 1// Created on: 2000-10-20
2// Created by: Julia DOROVSKIKH
973c2be1 3// Copyright (c) 2000-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
7fd59977 15
7fd59977 16
17#include <AIS.hxx>
42cf5bc1 18#include <AIS_MidPointRelation.hxx>
19#include <BRep_Tool.hxx>
20#include <BRepAdaptor_Curve.hxx>
21#include <BRepAdaptor_Surface.hxx>
22#include <DsgPrs_MidPointPresentation.hxx>
7fd59977 23#include <ElCLib.hxx>
42cf5bc1 24#include <gce_MakeLin.hxx>
7fd59977 25#include <Geom_Circle.hxx>
26#include <Geom_Ellipse.hxx>
42cf5bc1 27#include <Geom_Line.hxx>
28#include <Geom_Plane.hxx>
29#include <Geom_Transformation.hxx>
7fd59977 30#include <Geom_TrimmedCurve.hxx>
42cf5bc1 31#include <gp_Ax1.hxx>
32#include <gp_Ax2.hxx>
33#include <gp_Circ.hxx>
34#include <gp_Dir.hxx>
35#include <gp_Elips.hxx>
36#include <gp_Lin.hxx>
37#include <gp_Pln.hxx>
38#include <gp_Pnt.hxx>
39#include <Precision.hxx>
40#include <Prs3d_ArrowAspect.hxx>
41#include <Prs3d_DimensionAspect.hxx>
42#include <Prs3d_Drawer.hxx>
43#include <Prs3d_Presentation.hxx>
42cf5bc1 44#include <Select3D_SensitiveCurve.hxx>
45#include <Select3D_SensitiveSegment.hxx>
7fd59977 46#include <SelectMgr_EntityOwner.hxx>
f751596e 47#include <SelectMgr_Selection.hxx>
42cf5bc1 48#include <Standard_NotImplemented.hxx>
49#include <Standard_Type.hxx>
7fd59977 50#include <TopExp_Explorer.hxx>
42cf5bc1 51#include <TopoDS.hxx>
52#include <TopoDS_Shape.hxx>
7fd59977 53#include <TopoDS_Vertex.hxx>
54
92efcf78 55IMPLEMENT_STANDARD_RTTIEXT(AIS_MidPointRelation,AIS_Relation)
56
7fd59977 57//=======================================================================
58//function : AIS_MidPointRelation
59//purpose :
60//=======================================================================
61AIS_MidPointRelation::AIS_MidPointRelation(const TopoDS_Shape& aMidPointTool,
62 const TopoDS_Shape& FirstShape,
63 const TopoDS_Shape& SecondShape,
64 const Handle(Geom_Plane)& aPlane)
65:AIS_Relation(),
66 myTool(aMidPointTool)
67{
68 SetFirstShape(FirstShape);
69 SetSecondShape(SecondShape);
70 SetPlane(aPlane);
71 myPosition = aPlane->Pln().Location();
72}
73
74//=======================================================================
75//function : Compute
76//purpose :
77//=======================================================================
78void AIS_MidPointRelation::Compute(const Handle(PrsMgr_PresentationManager3d)&,
79 const Handle(Prs3d_Presentation)& aprs,
80 const Standard_Integer)
81{
7fd59977 82 if (myTool.ShapeType() == TopAbs_VERTEX)
83 {
84 gp_Pnt pp;
85 Standard_Boolean isonplane;
86 if ( AIS::ComputeGeometry(TopoDS::Vertex(myTool),pp,myPlane,isonplane) )
87 {
88 if ( !isonplane ) ComputeProjVertexPresentation(aprs,TopoDS::Vertex(myTool),pp);
89 }
90 myMidPoint = pp;
91 }
92 else return;
93
94 if ( myAutomaticPosition ) myPosition = myMidPoint;
95
96 switch (myFShape.ShapeType())
97 {
98 case TopAbs_FACE :
99 {
100 ComputeFaceFromPnt(aprs, Standard_True);
101 }
102 break;
103 case TopAbs_EDGE :
104 {
105 ComputeEdgeFromPnt(aprs, Standard_True);
106 }
107 break;
108 case TopAbs_VERTEX :
109 {
110 ComputeVertexFromPnt(aprs, Standard_True);
111 }
112 break;
113 default:
114 break;
115 }
116
117 switch (mySShape.ShapeType())
118 {
119 case TopAbs_FACE :
120 {
121 ComputeFaceFromPnt(aprs, Standard_False);
122 }
123 break;
124 case TopAbs_EDGE :
125 {
126 ComputeEdgeFromPnt(aprs, Standard_False);
127 }
128 break;
129 case TopAbs_VERTEX :
130 {
131 ComputeVertexFromPnt(aprs, Standard_False);
132 }
133 break;
134 default:
135 break;
136 }
137}
138
7fd59977 139//=======================================================================
140//function : ComputeSelection
141//purpose :
142//=======================================================================
143void AIS_MidPointRelation::ComputeSelection(const Handle(SelectMgr_Selection)& aSel,
144 const Standard_Integer)
145{
146 Handle(Select3D_SensitiveSegment) seg;
147 Handle(SelectMgr_EntityOwner) own = new SelectMgr_EntityOwner(this,7);
148
149 if ( !myMidPoint.IsEqual(myFAttach,Precision::Confusion()) )
150 {
151 // segment from mid point to the first geometry
152 seg = new Select3D_SensitiveSegment(own,myFAttach,myMidPoint);
153 aSel->Add(seg);
154 // segment from mid point to the second geometry
155 seg = new Select3D_SensitiveSegment(own,mySAttach,myMidPoint);
156 aSel->Add(seg);
157 }
158 if ( !myMidPoint.IsEqual(myPosition,Precision::Confusion()) )
159 {
160 // segment from mid point to the text position
161 seg = new Select3D_SensitiveSegment(own,myMidPoint,myPosition);
162 aSel->Add(seg);
163 }
164
165 // center of the symmetry - circle around the MidPoint
166 gp_Ax2 ax = myPlane->Pln().Position().Ax2();
167 ax.SetLocation(myMidPoint);
168 Standard_Real rad = myFAttach.Distance(myMidPoint)/20.0;
169 gp_Circ aCircleM (ax,rad);
543a9964 170 Handle(Geom_Curve) thecir = new Geom_Circle(aCircleM);
7fd59977 171 Handle(Select3D_SensitiveCurve) scurv = new Select3D_SensitiveCurve(own, thecir);
172 aSel->Add(scurv);
173
174 Handle(Geom_Curve) curv;
175 gp_Pnt firstp,lastp;
176 Standard_Boolean isInfinite,isOnPlane;
177 Handle(Geom_Curve) extCurv;
178
179 // segment on first curve
180 if ( myFShape.ShapeType() == TopAbs_EDGE )
181 {
182 TopoDS_Edge E = TopoDS::Edge(myFShape);
183 if ( !AIS::ComputeGeometry(E,curv,firstp,lastp,extCurv,isInfinite,isOnPlane,myPlane) ) return;
184 if ( curv->IsInstance(STANDARD_TYPE(Geom_Line)) ) // case of line
185 {
186 // segment on line
187 seg = new Select3D_SensitiveSegment(own,myFirstPnt1,myFirstPnt2);
188 aSel->Add(seg);
189 }
190 else if ( curv->IsInstance(STANDARD_TYPE(Geom_Circle)) ) // case of circle
191 {
192 // segment on circle
c5f3a425 193 Handle(Geom_Circle) thecirc = Handle(Geom_Circle)::DownCast (curv);
7fd59977 194 Standard_Real udeb = ElCLib::Parameter(thecirc->Circ(),myFirstPnt1);
195 Standard_Real ufin = ElCLib::Parameter(thecirc->Circ(),myFirstPnt2);
543a9964 196 Handle(Geom_Curve) thecu = new Geom_TrimmedCurve(thecirc,udeb,ufin);
7fd59977 197
198 scurv = new Select3D_SensitiveCurve(own, thecu);
199 aSel->Add(scurv);
200 }
201 else if ( curv->IsInstance(STANDARD_TYPE(Geom_Ellipse)) ) // case of ellipse
202 {
203 // segment on ellipse
c5f3a425 204 Handle(Geom_Ellipse) theEll = Handle(Geom_Ellipse)::DownCast (curv);
7fd59977 205 Standard_Real udeb = ElCLib::Parameter(theEll->Elips(),myFirstPnt1);
206 Standard_Real ufin = ElCLib::Parameter(theEll->Elips(),myFirstPnt2);
543a9964 207 Handle(Geom_Curve) thecu = new Geom_TrimmedCurve(theEll,udeb,ufin);
7fd59977 208
209 scurv = new Select3D_SensitiveCurve(own, thecu);
210 aSel->Add(scurv);
211 }
212 }
213
214 // segment on second curve
215 if ( mySShape.ShapeType() == TopAbs_EDGE )
216 {
217 TopoDS_Edge E = TopoDS::Edge(mySShape);
218 if ( !AIS::ComputeGeometry(E,curv,firstp,lastp,extCurv,isInfinite,isOnPlane,myPlane) ) return;
219 if ( curv->IsInstance(STANDARD_TYPE(Geom_Line)) ) // case of line
220 {
221 // segment on line
222 seg = new Select3D_SensitiveSegment(own,mySecondPnt1,mySecondPnt2);
223 aSel->Add(seg);
224 }
225 else if ( curv->IsInstance(STANDARD_TYPE(Geom_Circle)) ) // case of circle
226 {
227 // segment on circle
c5f3a425 228 Handle(Geom_Circle) thecirc = Handle(Geom_Circle)::DownCast (curv);
7fd59977 229 Standard_Real udeb = ElCLib::Parameter(thecirc->Circ(),mySecondPnt1);
230 Standard_Real ufin = ElCLib::Parameter(thecirc->Circ(),mySecondPnt2);
543a9964 231 Handle(Geom_Curve) thecu = new Geom_TrimmedCurve(thecirc,udeb,ufin);
7fd59977 232
233 scurv = new Select3D_SensitiveCurve(own, thecu);
234 aSel->Add(scurv);
235 }
236 else if ( curv->IsInstance(STANDARD_TYPE(Geom_Ellipse)) ) // case of ellipse
237 {
238 // segment on ellipse
c5f3a425 239 Handle(Geom_Ellipse) theEll = Handle(Geom_Ellipse)::DownCast (curv);
7fd59977 240 Standard_Real udeb = ElCLib::Parameter(theEll->Elips(),mySecondPnt1);
241 Standard_Real ufin = ElCLib::Parameter(theEll->Elips(),mySecondPnt2);
543a9964 242 Handle(Geom_Curve) thecu = new Geom_TrimmedCurve(theEll,udeb,ufin);
7fd59977 243
244 scurv = new Select3D_SensitiveCurve(own, thecu);
245 aSel->Add(scurv);
246 }
247 }
248}
249
250//=======================================================================
251//function : ComputeFaceFromPnt
252//purpose :
253//=======================================================================
254void AIS_MidPointRelation::ComputeFaceFromPnt(const Handle(Prs3d_Presentation)&,
255 const Standard_Boolean /*first*/)
256{
257}
258
259//=======================================================================
260//function : ComputeEdgeFromPnt
261//purpose :
262//=======================================================================
263void AIS_MidPointRelation::ComputeEdgeFromPnt(const Handle(Prs3d_Presentation)& aprs,
264 const Standard_Boolean first)
265{
266 TopoDS_Edge E;
267 if ( first ) E = TopoDS::Edge(myFShape);
268 else E = TopoDS::Edge(mySShape);
269
270 Handle(Geom_Curve) geom;
271 gp_Pnt ptat1,ptat2;
272 Handle(Geom_Curve) extCurv;
273 Standard_Boolean isInfinite,isOnPlane;
274 if ( !AIS::ComputeGeometry(E, geom, ptat1, ptat2, extCurv, isInfinite, isOnPlane, myPlane) ) return;
275
276 gp_Ax2 ax = myPlane->Pln().Position().Ax2();
277
278 if ( geom->IsInstance(STANDARD_TYPE(Geom_Line)) )
279 {
280 if ( !isInfinite ) ComputePointsOnLine(ptat1,ptat2,first);
281 else
282 {
c5f3a425 283 const gp_Lin& line = Handle(Geom_Line)::DownCast (geom)->Lin();
7fd59977 284 ComputePointsOnLine(line,first);
285 }
286 if ( first ) DsgPrs_MidPointPresentation::Add(aprs,myDrawer,ax,myMidPoint,myPosition,
287 myFAttach,myFirstPnt1,myFirstPnt2,first);
288 else DsgPrs_MidPointPresentation::Add(aprs,myDrawer,ax,myMidPoint,myPosition,
289 mySAttach,mySecondPnt1,mySecondPnt2,first);
290 }
291 else if ( geom->IsInstance(STANDARD_TYPE(Geom_Circle)) )
292 {
c5f3a425 293 Handle(Geom_Circle) geom_cir (Handle(Geom_Circle)::DownCast (geom));
7fd59977 294 gp_Circ circ (geom_cir->Circ());
295 ComputePointsOnCirc(circ,ptat1,ptat2,first);
296 if ( first ) DsgPrs_MidPointPresentation::Add(aprs,myDrawer,circ,myMidPoint,myPosition,
297 myFAttach,myFirstPnt1,myFirstPnt2,first);
298 else DsgPrs_MidPointPresentation::Add(aprs,myDrawer,circ,myMidPoint,myPosition,
299 mySAttach,mySecondPnt1,mySecondPnt2,first);
300 }
301 else if ( geom->IsInstance(STANDARD_TYPE(Geom_Ellipse)) )
302 {
c5f3a425 303 Handle(Geom_Ellipse) geom_ell (Handle(Geom_Ellipse)::DownCast (geom));
7fd59977 304 gp_Elips elips (geom_ell->Elips());
305 ComputePointsOnElips(elips,ptat1,ptat2,first);
306 if ( first ) DsgPrs_MidPointPresentation::Add(aprs,myDrawer,elips,myMidPoint,myPosition,
307 myFAttach,myFirstPnt1,myFirstPnt2,first);
308 else DsgPrs_MidPointPresentation::Add(aprs,myDrawer,elips,myMidPoint,myPosition,
309 mySAttach,mySecondPnt1,mySecondPnt2,first);
310 }
311 else return;
312
313 // projection on myPlane
314 if ( !isOnPlane ) ComputeProjEdgePresentation(aprs,E,geom,ptat1,ptat2);
315}
316
317//=======================================================================
318//function : ComputeVertexFromPnt
319//purpose :
320//=======================================================================
321void AIS_MidPointRelation::ComputeVertexFromPnt(const Handle(Prs3d_Presentation)& aprs,
322 const Standard_Boolean first)
323{
324 gp_Ax2 ax = myPlane->Pln().Position().Ax2();
325 if ( first )
326 {
327 Standard_Boolean isOnPlane;
328 TopoDS_Vertex V = TopoDS::Vertex(myFShape);
329 AIS::ComputeGeometry(V, myFAttach, myPlane, isOnPlane);
330 DsgPrs_MidPointPresentation::Add(aprs,myDrawer,ax,myMidPoint,myPosition,myFAttach,first);
331 if ( !isOnPlane ) ComputeProjVertexPresentation(aprs,V,myFAttach);
332 }
333 else
334 {
335 Standard_Boolean isOnPlane;
336 TopoDS_Vertex V = TopoDS::Vertex(mySShape);
337 AIS::ComputeGeometry(V, mySAttach, myPlane, isOnPlane);
338 DsgPrs_MidPointPresentation::Add(aprs,myDrawer,ax,myMidPoint,myPosition,mySAttach,first);
339 if ( !isOnPlane ) ComputeProjVertexPresentation(aprs,V,mySAttach);
340 }
341}
342
343//=======================================================================
344//function : ComputePointsOnLine
345//purpose :
346//=======================================================================
347void AIS_MidPointRelation::ComputePointsOnLine(const gp_Lin& aLin,
348 const Standard_Boolean first)
349{
350 Standard_Real ppar = ElCLib::Parameter(aLin,myMidPoint);
351 gp_Pnt anAttach = ElCLib::Value(ppar,aLin);
352
353 Standard_Real dist = anAttach.Distance(myMidPoint)/10.0;
354 if ( dist < Precision::Confusion() ) dist = 10.0;
355
356 Standard_Real fpar = ppar + dist;
357 Standard_Real spar = ppar - dist;
358
359 gp_Pnt aPnt1 = ElCLib::Value(fpar,aLin);
360 gp_Pnt aPnt2 = ElCLib::Value(spar,aLin);
361
362 if ( first )
363 {
364 myFAttach = anAttach;
365 myFirstPnt1 = aPnt1;
366 myFirstPnt2 = aPnt2;
367 }
368 else
369 {
370 mySAttach = anAttach;
371 mySecondPnt1 = aPnt1;
372 mySecondPnt2 = aPnt2;
373 }
374}
375
376//=======================================================================
377//function : ComputePointsOnLine
378//purpose :
379//=======================================================================
380void AIS_MidPointRelation::ComputePointsOnLine(const gp_Pnt& pnt1, const gp_Pnt& pnt2,
381 const Standard_Boolean first)
382{
383 gp_Vec aVec (pnt1,pnt2);
384 gp_Lin aLin (pnt1,gp_Dir(aVec));
385
386 Standard_Real fpar = ElCLib::Parameter(aLin,pnt1);
387 Standard_Real spar = ElCLib::Parameter(aLin,pnt2);
388 Standard_Real ppar = ElCLib::Parameter(aLin,myMidPoint);
389
390 gp_Pnt aProjPnt = ElCLib::Value(ppar,aLin);
391 Standard_Real dist = myMidPoint.Distance(aProjPnt);
392 Standard_Real ll = pnt1.Distance(pnt2);
393 Standard_Real segm = Min(dist,ll)*0.75;
394 if ( dist < Precision::Confusion() ) segm = ll*0.75;
395
396 gp_Pnt anAttach,aPnt1,aPnt2;
397 anAttach = aProjPnt;
398 gp_Vec aVecTr;
399 if ( ppar <= fpar )
400 {
401 aPnt2 = pnt1;
402 aVecTr = gp_Vec(pnt2,pnt1);
403 aVecTr.Normalize();
404 aPnt1 = aProjPnt.Translated(aVecTr*segm);
405 }
406 else if ( ppar >= spar )
407 {
408 aPnt1 = pnt2;
409 aVecTr = gp_Vec(pnt1,pnt2);
410 aVecTr.Normalize();
411 aPnt2 = aProjPnt.Translated(aVecTr*segm);
412 }
413 else
414 {
415 Standard_Real dp1 = aProjPnt.Distance(pnt1);
416 Standard_Real dp2 = aProjPnt.Distance(pnt2);
417
418 segm = Min(dist,dp1)*0.75;
419 aVecTr = gp_Vec(aProjPnt,pnt1);
420 aVecTr.Normalize();
421 aPnt1 = aProjPnt.Translated(aVecTr*segm);
422
423 segm = Min(dist,dp2)*0.75;
424 aVecTr = gp_Vec(aProjPnt,pnt2);
425 aVecTr.Normalize();
426 aPnt2 = aProjPnt.Translated(aVecTr*segm);
427 }
428
429 if ( first )
430 {
431 myFAttach = anAttach;
432 myFirstPnt1 = aPnt1;
433 myFirstPnt2 = aPnt2;
434 }
435 else
436 {
437 mySAttach = anAttach;
438 mySecondPnt1 = aPnt1;
439 mySecondPnt2 = aPnt2;
440 }
441}
442
443//=======================================================================
444//function : ComputePointsOnCirc
445//purpose :
446//=======================================================================
447void AIS_MidPointRelation::ComputePointsOnCirc(const gp_Circ& aCirc,
448 const gp_Pnt& pnt1, const gp_Pnt& pnt2,
449 const Standard_Boolean first)
450{
451 gp_Pnt curpos = myMidPoint;
452
453 // Case of confusion between the current position and the center
454 // of the circle -> we move the current position
455 Standard_Real confusion (Precision::Confusion());
456 gp_Pnt aCenter = aCirc.Location();
457 if ( aCenter.Distance(curpos) <= confusion )
458 {
459 gp_Vec vprec(aCenter, pnt1);
460 vprec.Normalize();
461 curpos.Translate(vprec*1e-5);
462 }
463
464 Standard_Real pcurpos = ElCLib::Parameter(aCirc,curpos);
465
c6541a0c 466 Standard_Real rad = M_PI / 5.0;
7fd59977 467 Standard_Real segm;
468
469 Standard_Real pFPnt;
470 Standard_Real pSPnt;
471
472 if ( pnt1.IsEqual(pnt2,confusion) ) // full circle
473 {
474 pFPnt = pcurpos - rad;
475 pSPnt = pcurpos + rad;
476 }
477 else
478 {
479 Standard_Real pFAttach = ElCLib::Parameter(aCirc,pnt1);
480 Standard_Real pSAttach = ElCLib::Parameter(aCirc,pnt2);
481
482 Standard_Real pSAttachM = pSAttach;
483 Standard_Real deltap = pSAttachM - pFAttach;
484 if ( deltap < 0 )
485 {
c6541a0c
D
486 deltap += 2 * M_PI;
487 pSAttachM += 2 * M_PI;
7fd59977 488 }
489 pSAttachM -= pFAttach;
490
c6541a0c 491 Standard_Real pmiddleout = pSAttachM/2.0 + M_PI;
7fd59977 492
493 Standard_Real pcurpos1 = pcurpos;
494 // define where curpos lays
495 if ( pcurpos1 < pFAttach )
496 {
c6541a0c 497 pcurpos1 = pcurpos1 + 2 * M_PI - pFAttach;
7fd59977 498 if ( pcurpos1 > pSAttachM ) // out
499 {
500 segm = Min(rad,deltap*0.75);
501 if ( pcurpos1 > pmiddleout )
502 {
503 pcurpos = pFAttach;
504 pFPnt = pFAttach;
505 pSPnt = pFAttach + segm;
506 }
507 else
508 {
509 pcurpos = pSAttach;
510 pFPnt = pSAttach - segm;
511 pSPnt = pSAttach;
512 }
513 }
514 else // on arc
515 {
516 Standard_Real dp1 = pcurpos1 - pFAttach;
517 Standard_Real dp2 = pSAttachM - pcurpos1;
518
519 segm = Min(rad,dp1*0.75);
520 pFPnt = pcurpos - segm;
521
522 segm = Min(rad,dp2*0.75);
523 pSPnt = pcurpos + segm;
524 }
525 }
526 else if ( pcurpos1 > (pFAttach + deltap) ) // out
527 {
528 pcurpos1 -= pFAttach;
529 segm = Min(rad,deltap*0.75);
530 if ( pcurpos1 > pmiddleout )
531 {
532 pcurpos = pFAttach;
533 pFPnt = pFAttach;
534 pSPnt = pFAttach + segm;
535 }
536 else
537 {
538 pcurpos = pSAttach;
539 pFPnt = pSAttach - segm;
540 pSPnt = pSAttach;
541 }
542 }
543 else // on arc
544 {
545 Standard_Real dp1 = pcurpos1 - pFAttach;
546 Standard_Real dp2 = pSAttach - pcurpos1;
547
548 segm = Min(rad,dp1*0.75);
549 pFPnt = pcurpos - segm;
550
551 segm = Min(rad,dp2*0.75);
552 pSPnt = pcurpos + segm;
553 }
554 }
555
556 if ( first )
557 {
558 myFAttach = ElCLib::Value(pcurpos,aCirc);
559 myFirstPnt1 = ElCLib::Value(pFPnt,aCirc);
560 myFirstPnt2 = ElCLib::Value(pSPnt,aCirc);
561 }
562 else
563 {
564 mySAttach = ElCLib::Value(pcurpos,aCirc);
565 mySecondPnt1 = ElCLib::Value(pFPnt,aCirc);
566 mySecondPnt2 = ElCLib::Value(pSPnt,aCirc);
567 }
568}
569
570//=======================================================================
571//function : ComputePointsOnElips
572//purpose :
573//=======================================================================
574void AIS_MidPointRelation::ComputePointsOnElips(const gp_Elips& anEll,
575 const gp_Pnt& pnt1, const gp_Pnt& pnt2,
576 const Standard_Boolean first)
577{
578 gp_Pnt curpos = myMidPoint;
579
580 // Case of confusion between the current position and the center
581 // of the circle -> we move the current position
582 Standard_Real confusion (Precision::Confusion());
583 gp_Pnt aCenter = anEll.Location();
584 if ( aCenter.Distance(curpos) <= confusion )
585 {
586 gp_Vec vprec(aCenter, pnt1);
587 vprec.Normalize();
588 curpos.Translate(vprec*1e-5);
589 }
590
591 Standard_Real pcurpos = ElCLib::Parameter(anEll,curpos);
592
c6541a0c 593 Standard_Real rad = M_PI / 5.0;
7fd59977 594 Standard_Real segm;
595
596 Standard_Real pFPnt;
597 Standard_Real pSPnt;
598
599 if ( pnt1.IsEqual(pnt2,confusion) ) // full circle
600 {
601 pFPnt = pcurpos - rad;
602 pSPnt = pcurpos + rad;
603 }
604 else
605 {
606 Standard_Real pFAttach = ElCLib::Parameter(anEll,pnt1);
607 Standard_Real pSAttach = ElCLib::Parameter(anEll,pnt2);
608
609 Standard_Real pSAttachM = pSAttach;
610 Standard_Real deltap = pSAttachM - pFAttach;
611 if ( deltap < 0 )
612 {
c6541a0c
D
613 deltap += 2 * M_PI;
614 pSAttachM += 2 * M_PI;
7fd59977 615 }
616 pSAttachM -= pFAttach;
617
c6541a0c 618 Standard_Real pmiddleout = pSAttachM / 2.0 + M_PI;
7fd59977 619
620 Standard_Real pcurpos1 = pcurpos;
621 // define where curpos lays
622 if ( pcurpos1 < pFAttach )
623 {
c6541a0c 624 pcurpos1 = pcurpos1 + 2 * M_PI - pFAttach;
7fd59977 625 if ( pcurpos1 > pSAttachM ) // out
626 {
627 segm = Min(rad,deltap*0.75);
628 if ( pcurpos1 > pmiddleout )
629 {
630 pcurpos = pFAttach;
631 pFPnt = pFAttach;
632 pSPnt = pFAttach + segm;
633 }
634 else
635 {
636 pcurpos = pSAttach;
637 pFPnt = pSAttach - segm;
638 pSPnt = pSAttach;
639 }
640 }
641 else // on arc
642 {
643 Standard_Real dp1 = pcurpos1 - pFAttach;
644 Standard_Real dp2 = pSAttachM - pcurpos1;
645
646 segm = Min(rad,dp1*0.75);
647 pFPnt = pcurpos - segm;
648
649 segm = Min(rad,dp2*0.75);
650 pSPnt = pcurpos + segm;
651 }
652 }
653 else if ( pcurpos1 > (pFAttach + deltap) ) // out
654 {
655 pcurpos1 -= pFAttach;
656 segm = Min(rad,deltap*0.75);
657 if ( pcurpos1 > pmiddleout )
658 {
659 pcurpos = pFAttach;
660 pFPnt = pFAttach;
661 pSPnt = pFAttach + segm;
662 }
663 else
664 {
665 pcurpos = pSAttach;
666 pFPnt = pSAttach - segm;
667 pSPnt = pSAttach;
668 }
669 }
670 else // on arc
671 {
672 Standard_Real dp1 = pcurpos1 - pFAttach;
673 Standard_Real dp2 = pSAttach - pcurpos1;
674
675 segm = Min(rad,dp1*0.75);
676 pFPnt = pcurpos - segm;
677
678 segm = Min(rad,dp2*0.75);
679 pSPnt = pcurpos + segm;
680 }
681 }
682
683 if ( first )
684 {
685 myFAttach = ElCLib::Value(pcurpos,anEll);
686 myFirstPnt1 = ElCLib::Value(pFPnt,anEll);
687 myFirstPnt2 = ElCLib::Value(pSPnt,anEll);
688 }
689 else
690 {
691 mySAttach = ElCLib::Value(pcurpos,anEll);
692 mySecondPnt1 = ElCLib::Value(pFPnt,anEll);
693 mySecondPnt2 = ElCLib::Value(pSPnt,anEll);
694 }
695}