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