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