Integration of OCCT 6.5.0 from SVN
[occt.git] / src / AIS / AIS_DiameterDimension.cxx
1 // File:        AIS_DiameterDimension.cdl
2 // Created:     Tue Dec  5 15:09:04 1996
3 // Modified     Mon 12-january-98
4 // Author:      Jacques MINOT/Odile Olivier/Sergey ZARITCHNY
5 //              <ODL>, <SZY>
6
7
8 #define BUC60915        //GG 05/06/01 Enable to compute the requested arrow size
9 //                      if any in all dimensions.
10
11 #include <Standard_NotImplemented.hxx>
12
13 #include <AIS_DiameterDimension.ixx>
14 #include <AIS_DimensionOwner.hxx>
15 #include <DsgPrs_DiameterPresentation.hxx>
16 #include <DsgPrs_RadiusPresentation.hxx>
17
18 #include <TCollection_ExtendedString.hxx>
19
20 #include <Prs3d_LengthAspect.hxx>
21 #include <Prs3d_ArrowAspect.hxx>
22 #include <Prs3d_Drawer.hxx>
23 #include <Prs3d_TextAspect.hxx>
24 #include <Prs3d_Text.hxx>
25
26 #include <Select3D_SensitiveSegment.hxx>
27 #include <Select3D_SensitiveBox.hxx>
28 #include <SelectMgr_EntityOwner.hxx>
29
30 #include <ElCLib.hxx>
31 #include <ElSLib.hxx>
32
33 #include <TopoDS.hxx>
34
35 #include <BRepAdaptor_Surface.hxx>
36 #include <BRepAdaptor_Curve.hxx>
37 #include <Adaptor3d_HCurve.hxx>
38
39 #include <Geom_Circle.hxx>
40 #include <Geom_TrimmedCurve.hxx>
41 #include <Geom_Plane.hxx>
42 #include <Geom_Surface.hxx>
43 #include <Geom_CylindricalSurface.hxx>
44 #include <Geom_SurfaceOfRevolution.hxx>
45 #include <Geom_CylindricalSurface.hxx>
46 #include <Geom_SurfaceOfLinearExtrusion.hxx>
47
48 #include <gp_Pln.hxx>
49 #include <gp_Pnt.hxx>
50 #include <gp_Lin.hxx>
51 #include <gp_Ax1.hxx>
52 #include <gp_Dir.hxx>
53 #include <gp_Vec.hxx>
54
55 #include <AIS.hxx>
56 #include <AIS_Drawer.hxx>
57
58 #include <GC_MakeCircle.hxx>
59
60 #include <Precision.hxx>
61
62 #include <TopExp_Explorer.hxx>
63
64 //=======================================================================
65 //function : Constructor
66 //purpose  : 
67 //=======================================================================
68
69 AIS_DiameterDimension::AIS_DiameterDimension(const TopoDS_Shape& aShape, 
70                                              const Standard_Real aVal, 
71                                              const TCollection_ExtendedString& aText)
72 :AIS_Relation(),
73  myDiamSymbol(Standard_True)
74 {
75   myPosition  = gp_Pnt(0.,0.,0.);
76   myFShape = aShape;
77   myVal = aVal;
78   myText = aText;
79   mySymbolPrs = DsgPrs_AS_LASTAR;
80   myAutomaticPosition = Standard_True;
81   myArrowSize = myVal / 100.;
82 }
83
84 //=======================================================================
85 //function : Constructor
86 //purpose  : 
87 //=======================================================================
88
89 AIS_DiameterDimension::AIS_DiameterDimension(const TopoDS_Shape& aShape, 
90                                              const Standard_Real aVal, 
91                                              const TCollection_ExtendedString& aText, 
92                                              const gp_Pnt& aPosition, 
93                                              const DsgPrs_ArrowSide aSymbolPrs,
94                                              const Standard_Boolean aDiamSymbol,
95                                              const Standard_Real anArrowSize)
96 :AIS_Relation(),
97  myDiamSymbol(aDiamSymbol)
98 {
99   myFShape = aShape;
100   myVal = aVal;
101   myText = aText;
102   mySymbolPrs = aSymbolPrs;
103   myPosition = aPosition;
104   myAutomaticPosition = Standard_False;
105 #ifdef BUC60915
106   SetArrowSize( anArrowSize );
107 #else
108   myArrowSize = anArrowSize;
109 #endif
110 }
111
112 //=======================================================================
113 //function : Compute
114 //purpose  : 
115 //=======================================================================
116
117 void AIS_DiameterDimension::Compute(
118        const Handle(PrsMgr_PresentationManager3d)& /*aPresentationManager*/,
119        const Handle(Prs3d_Presentation)& aPresentation, 
120        const Standard_Integer /*aMode*/)
121 {
122   aPresentation->Clear();
123
124   switch (myFShape.ShapeType()) {
125   case TopAbs_FACE :
126     {
127       // compute one face case
128       ComputeOneFaceDiameter (aPresentation);
129       break;
130     }
131   case TopAbs_EDGE:
132     {
133       ComputeOneEdgeDiameter (aPresentation);
134       break;
135     }
136   default:
137     break;
138   }
139
140 }
141
142 //=======================================================================
143 //function : Compute
144 //purpose  : to avoid warning
145 //=======================================================================
146
147 void AIS_DiameterDimension::Compute(const Handle(Prs3d_Projector)& aProjector,
148                                     const Handle(Prs3d_Presentation)& aPresentation)
149 {
150 // Standard_NotImplemented::Raise("AIS_DiameterDimension::Compute(const Handle(Prs3d_Projector)& aProjector, const Handle(Prs3d_Presentation)& aPresentation)");
151  PrsMgr_PresentableObject::Compute( aProjector , aPresentation ) ;
152 }
153
154 //=======================================================================
155 //function : Compute
156 //purpose  : to avoid warning
157 //=======================================================================
158
159 void AIS_DiameterDimension::Compute(const Handle(PrsMgr_PresentationManager2d)& aPresentationManager,
160                                     const Handle(Graphic2d_GraphicObject)& aPresentation,
161                                     const Standard_Integer aMode)
162 {
163 // Standard_NotImplemented::Raise("AIS_DiameterDimension::Compute(const Handle(PrsMgr_PresentationManager2d)& aPresentationManager, const Handle(Graphic2d_GraphicObject)& aPresentation, const Standard_Integer aMode)");
164  PrsMgr_PresentableObject::Compute( aPresentationManager ,aPresentation,aMode) ;
165 }
166
167 void AIS_DiameterDimension::Compute(const Handle_Prs3d_Projector& aProjector, const Handle_Geom_Transformation& aTransformation, const Handle_Prs3d_Presentation& aPresentation)
168 {
169 // Standard_NotImplemented::Raise("AIS_DiameterDimension::Compute(const Handle_Prs3d_Projector&, const Handle_Geom_Transformation&, const Handle_Prs3d_Presentation&)");
170   PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation ) ;
171 }
172
173 //=======================================================================
174 //function : ComputeSelection
175 //purpose  : 
176 //=======================================================================
177
178 void AIS_DiameterDimension::ComputeSelection(
179         const Handle(SelectMgr_Selection)& aSelection, 
180         const Standard_Integer /*aMode*/)
181 {
182   Handle(AIS_DimensionOwner) own = new AIS_DimensionOwner(this,7);
183   own->SetShape(myFShape);
184
185   if (!myIsAnArc) {
186     gp_Pnt        AttachmentPoint = myPosition;
187     Standard_Real parat    = ElCLib::Parameter(myCircle,AttachmentPoint);
188     gp_Pnt        ptoncirc = ElCLib::Value    (parat,myCircle);
189     
190     // ligne de cote
191     
192     gp_Pnt        center  = myCircle.Location();
193     gp_Vec        vecrap  (ptoncirc,center);
194     
195     Standard_Real dist    = center.Distance(AttachmentPoint);
196     Standard_Real aRadius = myCircle.Radius();
197     Standard_Real inside  = Standard_False;
198     
199     gp_Pnt pt1 = AttachmentPoint;
200     if (dist < aRadius) {
201       pt1 = ptoncirc;
202       dist = aRadius;
203       inside = Standard_True;
204     }
205     vecrap.Normalize();
206     vecrap *= (dist+aRadius);
207     gp_Pnt        OppositePoint = pt1.Translated(vecrap);
208     
209     if ( pt1.Distance(OppositePoint)>=Precision::Confusion()) {
210       Handle(Select3D_SensitiveSegment) 
211         seg = new Select3D_SensitiveSegment(own,pt1 ,OppositePoint);
212       aSelection->Add(seg);
213     }
214   }
215   else
216     ComputeArcSelection(aSelection);
217
218   // Text
219   Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6));
220   Handle( Select3D_SensitiveBox ) box = new Select3D_SensitiveBox( own,
221                                                                    myPosition.X(),
222                                                                    myPosition.Y(),
223                                                                    myPosition.Z(),
224                                                                    myPosition.X() + size,
225                                                                    myPosition.Y() + size,
226                                                                    myPosition.Z() + size);
227   aSelection->Add(box);
228 }
229 //==========================================================================
230 // function : ComputeArcSelection
231 // purpose  : 
232 //           
233 //==========================================================================
234
235 void AIS_DiameterDimension::ComputeArcSelection(const Handle(SelectMgr_Selection)& aSelection)
236 {
237
238   Standard_Real fpara; 
239   Standard_Real lpara; 
240   fpara = myFirstPar;
241   lpara = myLastPar;
242
243   Handle(SelectMgr_EntityOwner) own = new SelectMgr_EntityOwner(this,7);
244   gp_Pnt theCenter = myCircle.Location();
245   while (lpara > 2*PI) {
246     fpara -= 2*PI;
247     lpara -= 2*PI;
248   }
249   Standard_Real parat = ElCLib::Parameter(myCircle,myPosition);
250   Standard_Boolean otherside(Standard_False);
251   gp_Pnt attpoint = myPosition;
252
253   if (!AIS::InDomain(fpara,lpara,parat)) {
254     Standard_Real otherpar = parat + PI;
255     if (otherpar > 2*PI) otherpar -= 2*PI;
256     if (AIS::InDomain(fpara,lpara,otherpar)) {
257       parat = otherpar;
258       otherside = Standard_True;
259     }
260     else {
261       Standard_Real ecartpar = Min(Abs(fpara-parat),
262                                    Abs(lpara-parat));
263       Standard_Real ecartoth = Min(Abs(fpara-otherpar),
264                                    Abs(lpara-otherpar));
265       if (ecartpar <= ecartoth) {
266         if (parat < fpara) parat = fpara;
267         else parat = lpara;
268       }
269       else {
270         otherside = Standard_True;
271         if (otherpar < fpara) parat = fpara;
272         else parat = lpara;
273       }
274       gp_Pnt ptdir = ElCLib::Value(parat,myCircle);
275       gp_Lin lsup(theCenter,
276                   gp_Dir(ptdir.XYZ()-theCenter.XYZ()));
277       Standard_Real parpos = ElCLib::Parameter(lsup,myPosition);
278       attpoint = ElCLib::Value(parpos,lsup);
279     }
280   }
281   gp_Pnt ptoncirc = ElCLib::Value(parat,myCircle);
282   gp_Lin L (theCenter,gp_Dir(attpoint.XYZ()-theCenter.XYZ()));
283   gp_Pnt firstpoint = attpoint;
284   gp_Pnt drawtopoint = ptoncirc;
285
286   if (!otherside) {
287     Standard_Real uatt = ElCLib::Parameter(L,attpoint);
288     Standard_Real uptc = ElCLib::Parameter(L,ptoncirc);
289     if (Abs(uatt) > Abs(uptc)) {
290       drawtopoint = theCenter;
291     }
292     else {
293       firstpoint = theCenter;
294     }
295   }
296
297   Handle(Select3D_SensitiveSegment) seg = new Select3D_SensitiveSegment(own,firstpoint,drawtopoint);
298   aSelection->Add(seg);
299 }
300
301 //=======================================================================
302 //function : ComputeOneFaceDiameter
303 //purpose  : 
304 //=======================================================================
305
306 void AIS_DiameterDimension::ComputeOneFaceDiameter(
307         const Handle(Prs3d_Presentation)& aPresentation)
308 {
309   //cout<<"AIS_DiameterDimension::ComputeOneFaceDiameter"<<endl;
310
311   gp_Pln aPln;
312   Handle( Geom_Surface ) aBasisSurf;
313   AIS_KindOfSurface aSurfType;
314   Standard_Real Offset;
315   if( myAutomaticPosition )
316     AIS::GetPlaneFromFace( TopoDS::Face(  myFShape),
317                           aPln,
318                           aBasisSurf,
319                           aSurfType,
320                           Offset ) ;
321   
322   if ( aSurfType == AIS_KOS_Plane )
323     ComputeOnePlanarFaceDiameter( aPresentation );
324   else 
325     ComputeOneCylFaceDiameter( aPresentation, aSurfType, aBasisSurf );
326
327 }
328
329
330 //=======================================================================
331 //function : ComputeOneCylFaceDiameter
332 //purpose  : 
333 //=======================================================================
334
335 void AIS_DiameterDimension::ComputeOneCylFaceDiameter
336   (const Handle(Prs3d_Presentation)& aPresentation,
337    const AIS_KindOfSurface  aSurfType,
338    const Handle( Geom_Surface )&  aBasisSurf )
339 {
340   gp_Pnt curPos;
341   if( myAutomaticPosition )
342     {
343       BRepAdaptor_Surface surf1(TopoDS::Face(myFShape));
344       Standard_Real uFirst, uLast, vFirst, vLast;
345       uFirst = surf1.FirstUParameter();
346       uLast  = surf1.LastUParameter();
347       vFirst = surf1.FirstVParameter();
348       vLast  = surf1.LastVParameter();
349       Standard_Real uMid = (uFirst + uLast)*0.5;
350       Standard_Real vMid = (vFirst + vLast)*0.5;
351       surf1.D0(uMid, vMid, curPos);
352       Handle( Adaptor3d_HCurve ) BasisCurve;
353       //Standard_Real Param;
354       Standard_Boolean ExpectedType = Standard_False;
355       if (aSurfType == AIS_KOS_Cylinder)
356         {
357           ExpectedType = Standard_True;
358         }
359       else 
360         if (aSurfType == AIS_KOS_Revolution)
361         {
362           BasisCurve = surf1.BasisCurve();
363           if (BasisCurve->GetType() == GeomAbs_Line) 
364             ExpectedType = Standard_True;
365         }
366       else if (aSurfType == AIS_KOS_Extrusion)
367         {
368           BasisCurve = surf1.BasisCurve();
369           if ( BasisCurve->GetType() == GeomAbs_Circle )
370             ExpectedType = Standard_True;
371         }
372       if(!ExpectedType) {
373         Standard_ConstructionError::Raise("AIS:: Not expected type of surface") ;
374           return;
375         }
376       //      
377       Handle(Geom_Curve) aCurve;
378       aCurve =   aBasisSurf->VIso(vMid);
379       if (aCurve->DynamicType() == STANDARD_TYPE(Geom_Circle)) 
380         {
381           myCircle = Handle(Geom_Circle)::DownCast(aCurve)->Circ();//gp_Circ
382         }
383       else if (aCurve->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
384         Handle(Geom_TrimmedCurve) tCurve = Handle(Geom_TrimmedCurve)::DownCast(aCurve); 
385         aCurve = tCurve->BasisCurve();
386         uFirst = tCurve->FirstParameter();
387         uLast  = tCurve->LastParameter();
388         if (aCurve->DynamicType() == STANDARD_TYPE(Geom_Circle))
389           myCircle = Handle(Geom_Circle)::DownCast(aCurve)->Circ();//gp_Circ
390       }
391       else {
392         // compute a circle from 3 points on "aCurve"
393         gp_Pnt P1, P2;
394         surf1.D0(uFirst, vMid, P1);
395         surf1.D0(uLast, vMid, P2);
396         GC_MakeCircle mkCirc(P1, curPos, P2);
397         myCircle = mkCirc.Value()->Circ();
398       } 
399       myCircle.SetRadius(myVal/2.);
400       myPlane = new Geom_Plane(gp_Pln(gp_Ax3(myCircle.Position())));//gp_Circ
401       gp_Vec v1(myCircle.Location(), curPos);
402       v1.Normalize();
403       v1 = v1 * myVal*1.2;
404       myPosition = myCircle.Location().Translated(v1); 
405 //    IsArc ?
406       gp_Pnt p1, p2;
407       p1 = ElCLib::Value (uFirst, myCircle);
408       p2 = ElCLib::Value (uLast,  myCircle);
409       if ( p1.IsEqual(p2, Precision::Confusion()) ) 
410         myIsAnArc = Standard_False;
411       else myIsAnArc = Standard_True;
412       myFirstPar =  uFirst;
413       myLastPar  =  uLast;
414 //    myPosition = curPos;
415       myAutomaticPosition = Standard_True;   
416       if ( myIsSetBndBox )
417         myPosition = AIS::TranslatePointToBound( myPosition, gp_Dir( gp_Vec( myCircle.Location(),
418                                                                             myPosition ) ), myBndBox );
419     }
420   else { // !AutomaticPosition
421     curPos = myPosition;
422     curPos = AIS::ProjectPointOnPlane( curPos, myPlane->Pln() );
423     myPosition = curPos;
424   }
425  
426   Handle(Prs3d_LengthAspect) la = myDrawer->LengthAspect();
427   Handle(Prs3d_ArrowAspect) arr = la->Arrow1Aspect();
428   
429   // size
430 #ifdef BUC60915
431   if( !myArrowSizeIsDefined ) {
432     myArrowSize = Min(myArrowSize,myCircle.Radius()/5.);
433   }
434   arr->SetLength(myArrowSize);
435 #else
436   if (myCircle.Radius()/5. > myArrowSize) {
437     arr->SetLength(myArrowSize);
438   }
439   else {
440     arr->SetLength(myCircle.Radius()/5.);
441   }
442 #endif
443   
444   //cout<<"AIS_DiameterDimension:: add Prs"<<endl;
445   if( myIsAnArc ) 
446     DsgPrs_DiameterPresentation::Add(aPresentation, myDrawer, myText, myPosition,
447                                      myCircle, myFirstPar, myLastPar, mySymbolPrs, myDiamSymbol);
448   else
449     DsgPrs_DiameterPresentation::Add(aPresentation, myDrawer, myText, myPosition,
450                                      myCircle, DsgPrs_AS_BOTHAR, myDiamSymbol);
451
452
453 }
454
455
456 //=======================================================================
457 //function : ComputeCircleDiameter
458 //purpose  : 
459 //=======================================================================
460
461 void AIS_DiameterDimension::ComputeCircleDiameter(const Handle(Prs3d_Presentation)& aPresentation)
462 {
463   gp_Pnt center = myCircle.Location();
464   Standard_Real rad = myCircle.Radius();
465   gp_Pnt curpos;
466
467   if (myAutomaticPosition) {
468 // we compute 1 point on the circle
469     myPlane = new Geom_Plane(gp_Pln(gp_Ax3(myCircle.Position())));//gp_Circ
470     gp_Dir xdir = myCircle.XAxis().Direction();
471     Standard_Real deport = rad *1.2;
472     curpos = center.Translated( gp_Vec(xdir)*deport );
473     SetPosition (curpos);// myPosition = curpos
474     myAutomaticPosition = Standard_True; 
475     if (myIsSetBndBox)
476       myPosition = AIS::TranslatePointToBound( myPosition, gp_Dir( gp_Vec( myCircle.Location(),
477                                                                           myPosition ) ), myBndBox );
478   }
479   else {
480     curpos = myPosition;
481         // VRO (2007-05-17) inserted this IF.
482         if (myPlane.IsNull())
483                 myPlane = new Geom_Plane(gp_Pln(gp_Ax3(myCircle.Position())));
484     myPosition = AIS::ProjectPointOnPlane( curpos, myPlane->Pln() );
485   }
486
487   // size
488   Handle(Prs3d_LengthAspect) LA = myDrawer->LengthAspect();
489   Handle(Prs3d_ArrowAspect) arr = LA->Arrow1Aspect();
490
491 #ifdef BUC60915
492   if( !myArrowSizeIsDefined ) {
493     myArrowSize = Min(myArrowSize,myCircle.Radius()/5.);
494   }
495   arr->SetLength(myArrowSize);
496 #else
497   if (myCircle.Radius()/5. > myArrowSize) {
498     arr->SetLength(myArrowSize);
499   }
500   else {
501     arr->SetLength(myCircle.Radius()/5.);
502   }
503 #endif
504   
505   DsgPrs_DiameterPresentation::Add(aPresentation, myDrawer, myText, myPosition, myCircle,
506                                    DsgPrs_AS_BOTHAR, myDiamSymbol );
507
508 }
509
510 //==========================================================================
511 // function : ComputeArcDiameter
512 // purpose  : 
513 //           
514 //==========================================================================
515
516 void AIS_DiameterDimension::ComputeArcDiameter(
517                         const Handle(Prs3d_Presentation)& aPresentation,
518                         const gp_Pnt& pfirst,
519                         const gp_Pnt& pend)
520 {
521
522   gp_Pnt center = myCircle.Location();
523   Standard_Real rad = myCircle.Radius();
524
525   gp_Pnt curpos;
526   Standard_Real parfirst, parend;
527
528   parfirst = ElCLib::Parameter(myCircle, pfirst);
529   parend   = ElCLib::Parameter(myCircle, pend);
530   myFirstPar = parfirst;
531   myLastPar  = parend;
532   if ( parfirst > parend) {
533     parfirst -= 2*PI;
534   }
535   if (myAutomaticPosition) {
536     Standard_Real pcurpos = (parfirst + parend)/2.;
537     curpos = ElCLib::Value(pcurpos, myCircle);
538     myPlane = new Geom_Plane(gp_Pln(gp_Ax3(myCircle.Position())));//gp_Circ
539     gp_Dir vdir(gp_Vec(myCircle.Location(),curpos));
540     Standard_Real deport = rad * 1.2;
541     curpos = center.Translated( gp_Vec(vdir)*deport );
542
543     SetPosition (curpos);
544     myAutomaticPosition = Standard_True; 
545   
546     if ( myIsSetBndBox )
547       myPosition = AIS::TranslatePointToBound( myPosition, gp_Dir( gp_Vec( myCircle.Location(),
548                                                                           myPosition ) ), myBndBox );
549  
550   }
551   else {
552     curpos = myPosition;
553     myPosition = AIS::ProjectPointOnPlane( curpos, myPlane->Pln() );
554   }
555   
556   // size
557
558   Handle(Prs3d_LengthAspect) LA = myDrawer->LengthAspect();
559   Handle(Prs3d_ArrowAspect) arr = LA->Arrow1Aspect();
560
561 #ifdef BUC60915
562   if( !myArrowSizeIsDefined ) {
563     myArrowSize = Min(myArrowSize,myCircle.Radius()/5.);
564   }
565   arr->SetLength(myArrowSize);
566 #else
567   if (myCircle.Radius()/5. > myArrowSize) {
568     arr->SetLength(myArrowSize);
569   }
570   else {
571     arr->SetLength(myCircle.Radius()/5.);
572   }
573 #endif
574     
575   // Display
576   DsgPrs_DiameterPresentation::Add (aPresentation, myDrawer, myText, myPosition, myCircle, 
577                                   parfirst, parend, mySymbolPrs, myDiamSymbol);
578  
579 }
580
581
582 //==========================================================================
583 // function : ComputeOneEdgeDiameter
584 // purpose  : 
585 //           
586 //==========================================================================
587
588 void AIS_DiameterDimension::ComputeOneEdgeDiameter(const Handle(Prs3d_Presentation)& aPresentation)
589 {
590   gp_Pnt ptfirst,ptend;
591   Handle(Geom_Curve) curv;
592   if (!AIS::ComputeGeometry(TopoDS::Edge(myFShape),curv,ptfirst,ptend)) return;
593
594   Handle(Geom_Circle) circ = Handle(Geom_Circle)::DownCast(curv);
595   if ( circ.IsNull()) return;
596   
597   myCircle = circ->Circ();
598   myCircle.SetRadius(myVal/2.);
599   if ( ptfirst.IsEqual(ptend, Precision::Confusion()) ) {
600     myIsAnArc = Standard_False;
601     ComputeCircleDiameter(aPresentation);
602   }
603   else {
604     myIsAnArc = Standard_True;
605     ComputeArcDiameter(aPresentation,ptfirst,ptend );
606   }
607 }
608
609 //===================================================================
610 //function : CircleFromPlanarFace
611 //purpose  : if possible computes circle from planar face
612 //=======================================================================
613 static Standard_Boolean CircleFromPlanarFace(const TopoDS_Face& aFace,
614                                              Handle(Geom_Curve)& aCurve, 
615                                              gp_Pnt & ptfirst,  gp_Pnt & ptend)
616 {
617   TopExp_Explorer ExploEd( aFace, TopAbs_EDGE );
618   for ( ; ExploEd.More(); ExploEd.Next())
619     {
620       TopoDS_Edge curedge =  TopoDS::Edge( ExploEd.Current() );
621       if (AIS::ComputeGeometry(curedge, aCurve, ptfirst, ptend))
622         if(aCurve->IsInstance(STANDARD_TYPE(Geom_Circle))  && 
623            !Handle(Geom_Circle)::DownCast(aCurve).IsNull())
624           return Standard_True;
625     } 
626   return Standard_False;
627 }
628
629 //=======================================================================
630 //function : ComputeOnePlanarFaceDiameter
631 //purpose  : 
632 //=======================================================================
633
634 void AIS_DiameterDimension::ComputeOnePlanarFaceDiameter(const Handle(Prs3d_Presentation)& aPresentation)
635 {
636   gp_Pnt curPos ;
637 #ifndef DEB
638   Standard_Real parfirst =0., parend =0.; 
639 #else
640   Standard_Real parfirst, parend; 
641 #endif
642   if (myAutomaticPosition) {
643     Handle(Geom_Curve) curv;
644     gp_Pnt ptfirst,ptend;
645
646     if( !CircleFromPlanarFace( TopoDS::Face( myFShape ), curv, ptfirst, ptend) )  {
647       Standard_ConstructionError::Raise("AIS:: Curve is not a circle or is Null") ;
648         return;
649       }
650
651     myCircle = Handle(Geom_Circle)::DownCast(curv)->Circ();
652     if ( ptfirst.IsEqual(ptend, Precision::Confusion()) )
653       myIsAnArc = Standard_False;
654     else
655       myIsAnArc = Standard_True;
656     myCircle.SetRadius(myVal/2.);//
657     BRepAdaptor_Surface surfAlgo (TopoDS::Face(myFShape));
658     myPlane = new Geom_Plane(gp_Pln(gp_Ax3(myCircle.Position())));//gp_Circ
659     gp_Pnt center = myCircle.Location();
660     Standard_Real rad = myCircle.Radius();
661     Standard_Real deport = rad * 1.2;
662     if(! myIsAnArc ) { // Circle
663       gp_Dir xdir = myCircle.XAxis().Direction();
664       curPos = center.Translated( gp_Vec(xdir)*deport );
665     }
666     else { // Arc
667       parfirst = ElCLib::Parameter(myCircle, ptfirst);
668       parend   = ElCLib::Parameter(myCircle, ptend);
669       if ( parfirst > parend) {
670         parfirst -= 2*PI;
671       }
672       Standard_Real parcurPos = (parfirst + parend) * 0.5;
673       curPos = ElCLib::Value(parcurPos, myCircle);
674       gp_Vec v1( center, curPos );
675       v1.Normalize();
676       curPos = center.Translated( v1 * deport );
677     }
678     myFirstPar = parfirst;
679     myLastPar  = parend;
680     myPosition = curPos;
681     myAutomaticPosition = Standard_True;    
682     if ( myIsSetBndBox )
683       myPosition = AIS::TranslatePointToBound( myPosition, gp_Dir( gp_Vec( myCircle.Location(),
684                                                                           myPosition ) ), myBndBox );
685   } else 
686     {
687       // !myAutomaticPosition
688       // Project point on the plane of face
689       curPos = myPosition;
690       curPos = AIS::ProjectPointOnPlane( curPos, myPlane->Pln() );
691       myPosition = curPos;
692     }
693
694   
695   Handle(Prs3d_LengthAspect) la = myDrawer->LengthAspect();
696   Handle(Prs3d_ArrowAspect) arr = la->Arrow1Aspect();
697
698   // size
699 #ifdef BUC60915
700   if( !myArrowSizeIsDefined ) {
701     myArrowSize = Min(myArrowSize,myCircle.Radius()/5.);
702   }
703   arr->SetLength(myArrowSize);
704 #else
705   if (myCircle.Radius()/5. > myArrowSize) {
706     arr->SetLength(myArrowSize);
707   }
708   else {
709     arr->SetLength(myCircle.Radius()/5.);
710   }
711 #endif
712         
713   if(! myIsAnArc )
714     DsgPrs_DiameterPresentation::Add(aPresentation, myDrawer, myText, myPosition,
715                                      myCircle, DsgPrs_AS_BOTHAR, myDiamSymbol);
716   else 
717     DsgPrs_DiameterPresentation::Add(aPresentation, myDrawer, myText, myPosition,
718                                      myCircle, myFirstPar, myLastPar, mySymbolPrs, myDiamSymbol );
719 }
720