1 // Created on: 2000-10-20
2 // Created by: Julia DOROVSKIKH
3 // Copyright (c) 2000-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
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
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.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <PrsDim_MidPointRelation.hxx>
17
18 #include <PrsDim.hxx>
19 #include <BRep_Tool.hxx>
20 #include <BRepAdaptor_Curve.hxx>
21 #include <BRepAdaptor_Surface.hxx>
22 #include <DsgPrs_MidPointPresentation.hxx>
23 #include <ElCLib.hxx>
24 #include <gce_MakeLin.hxx>
25 #include <Geom_Circle.hxx>
26 #include <Geom_Ellipse.hxx>
27 #include <Geom_Line.hxx>
28 #include <Geom_Plane.hxx>
29 #include <Geom_TrimmedCurve.hxx>
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>
43 #include <Select3D_SensitiveCurve.hxx>
44 #include <Select3D_SensitiveSegment.hxx>
45 #include <SelectMgr_EntityOwner.hxx>
46 #include <SelectMgr_Selection.hxx>
47 #include <Standard_NotImplemented.hxx>
48 #include <TopExp_Explorer.hxx>
49 #include <TopoDS.hxx>
50 #include <TopoDS_Shape.hxx>
51 #include <TopoDS_Vertex.hxx>
52
IMPLEMENT_STANDARD_RTTIEXT(PrsDim_MidPointRelation,PrsDim_Relation)53 IMPLEMENT_STANDARD_RTTIEXT(PrsDim_MidPointRelation, PrsDim_Relation)
54
55 //=======================================================================
56 //function : PrsDim_MidPointRelation
57 //purpose :
58 //=======================================================================
59 PrsDim_MidPointRelation::PrsDim_MidPointRelation(const TopoDS_Shape& aMidPointTool,
60 const TopoDS_Shape& FirstShape,
61 const TopoDS_Shape& SecondShape,
62 const Handle(Geom_Plane)& aPlane)
63 :PrsDim_Relation(),
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 //=======================================================================
Compute(const Handle (PrsMgr_PresentationManager)&,const Handle (Prs3d_Presentation)& aprs,const Standard_Integer)76 void PrsDim_MidPointRelation::Compute (const Handle(PrsMgr_PresentationManager)& ,
77 const Handle(Prs3d_Presentation)& aprs,
78 const Standard_Integer )
79 {
80 if (myTool.ShapeType() == TopAbs_VERTEX)
81 {
82 gp_Pnt pp;
83 Standard_Boolean isonplane;
84 if ( PrsDim::ComputeGeometry(TopoDS::Vertex(myTool),pp,myPlane,isonplane) )
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
137 //=======================================================================
138 //function : ComputeSelection
139 //purpose :
140 //=======================================================================
ComputeSelection(const Handle (SelectMgr_Selection)& aSel,const Standard_Integer)141 void PrsDim_MidPointRelation::ComputeSelection(const Handle(SelectMgr_Selection)& aSel,
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);
168 Handle(Geom_Curve) thecir = new Geom_Circle(aCircleM);
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);
181 if ( !PrsDim::ComputeGeometry(E,curv,firstp,lastp,extCurv,isInfinite,isOnPlane,myPlane) ) return;
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
191 Handle(Geom_Circle) thecirc = Handle(Geom_Circle)::DownCast (curv);
192 Standard_Real udeb = ElCLib::Parameter(thecirc->Circ(),myFirstPnt1);
193 Standard_Real ufin = ElCLib::Parameter(thecirc->Circ(),myFirstPnt2);
194 Handle(Geom_Curve) thecu = new Geom_TrimmedCurve(thecirc,udeb,ufin);
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
202 Handle(Geom_Ellipse) theEll = Handle(Geom_Ellipse)::DownCast (curv);
203 Standard_Real udeb = ElCLib::Parameter(theEll->Elips(),myFirstPnt1);
204 Standard_Real ufin = ElCLib::Parameter(theEll->Elips(),myFirstPnt2);
205 Handle(Geom_Curve) thecu = new Geom_TrimmedCurve(theEll,udeb,ufin);
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);
216 if ( !PrsDim::ComputeGeometry(E,curv,firstp,lastp,extCurv,isInfinite,isOnPlane,myPlane) ) return;
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
226 Handle(Geom_Circle) thecirc = Handle(Geom_Circle)::DownCast (curv);
227 Standard_Real udeb = ElCLib::Parameter(thecirc->Circ(),mySecondPnt1);
228 Standard_Real ufin = ElCLib::Parameter(thecirc->Circ(),mySecondPnt2);
229 Handle(Geom_Curve) thecu = new Geom_TrimmedCurve(thecirc,udeb,ufin);
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
237 Handle(Geom_Ellipse) theEll = Handle(Geom_Ellipse)::DownCast (curv);
238 Standard_Real udeb = ElCLib::Parameter(theEll->Elips(),mySecondPnt1);
239 Standard_Real ufin = ElCLib::Parameter(theEll->Elips(),mySecondPnt2);
240 Handle(Geom_Curve) thecu = new Geom_TrimmedCurve(theEll,udeb,ufin);
241
242 scurv = new Select3D_SensitiveCurve(own, thecu);
243 aSel->Add(scurv);
244 }
245 }
246 }
247
248 //=======================================================================
249 //function : ComputeFaceFromPnt
250 //purpose :
251 //=======================================================================
ComputeFaceFromPnt(const Handle (Prs3d_Presentation)&,const Standard_Boolean)252 void PrsDim_MidPointRelation::ComputeFaceFromPnt(const Handle(Prs3d_Presentation)&,
253 const Standard_Boolean /*first*/)
254 {
255 }
256
257 //=======================================================================
258 //function : ComputeEdgeFromPnt
259 //purpose :
260 //=======================================================================
ComputeEdgeFromPnt(const Handle (Prs3d_Presentation)& aprs,const Standard_Boolean first)261 void PrsDim_MidPointRelation::ComputeEdgeFromPnt(const Handle(Prs3d_Presentation)& aprs,
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;
272 if ( !PrsDim::ComputeGeometry(E, geom, ptat1, ptat2, extCurv, isInfinite, isOnPlane, myPlane) ) return;
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 {
281 const gp_Lin& line = Handle(Geom_Line)::DownCast (geom)->Lin();
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 {
291 Handle(Geom_Circle) geom_cir (Handle(Geom_Circle)::DownCast (geom));
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 {
301 Handle(Geom_Ellipse) geom_ell (Handle(Geom_Ellipse)::DownCast (geom));
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 //=======================================================================
ComputeVertexFromPnt(const Handle (Prs3d_Presentation)& aprs,const Standard_Boolean first)319 void PrsDim_MidPointRelation::ComputeVertexFromPnt(const Handle(Prs3d_Presentation)& aprs,
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);
327 PrsDim::ComputeGeometry(V, myFAttach, myPlane, isOnPlane);
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);
335 PrsDim::ComputeGeometry(V, mySAttach, myPlane, isOnPlane);
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 //=======================================================================
ComputePointsOnLine(const gp_Lin & aLin,const Standard_Boolean first)345 void PrsDim_MidPointRelation::ComputePointsOnLine(const gp_Lin& aLin,
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 //=======================================================================
ComputePointsOnLine(const gp_Pnt & pnt1,const gp_Pnt & pnt2,const Standard_Boolean first)378 void PrsDim_MidPointRelation::ComputePointsOnLine(const gp_Pnt& pnt1, const gp_Pnt& pnt2,
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 //=======================================================================
ComputePointsOnCirc(const gp_Circ & aCirc,const gp_Pnt & pnt1,const gp_Pnt & pnt2,const Standard_Boolean first)445 void PrsDim_MidPointRelation::ComputePointsOnCirc(const gp_Circ& aCirc,
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
464 Standard_Real rad = M_PI / 5.0;
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 {
484 deltap += 2 * M_PI;
485 pSAttachM += 2 * M_PI;
486 }
487 pSAttachM -= pFAttach;
488
489 Standard_Real pmiddleout = pSAttachM/2.0 + M_PI;
490
491 Standard_Real pcurpos1 = pcurpos;
492 // define where curpos lays
493 if ( pcurpos1 < pFAttach )
494 {
495 pcurpos1 = pcurpos1 + 2 * M_PI - pFAttach;
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 //=======================================================================
ComputePointsOnElips(const gp_Elips & anEll,const gp_Pnt & pnt1,const gp_Pnt & pnt2,const Standard_Boolean first)572 void PrsDim_MidPointRelation::ComputePointsOnElips(const gp_Elips& anEll,
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
591 Standard_Real rad = M_PI / 5.0;
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 {
611 deltap += 2 * M_PI;
612 pSAttachM += 2 * M_PI;
613 }
614 pSAttachM -= pFAttach;
615
616 Standard_Real pmiddleout = pSAttachM / 2.0 + M_PI;
617
618 Standard_Real pcurpos1 = pcurpos;
619 // define where curpos lays
620 if ( pcurpos1 < pFAttach )
621 {
622 pcurpos1 = pcurpos1 + 2 * M_PI - pFAttach;
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 }
694