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