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