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