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