0024023: Revamp the OCCT Handle -- ambiguity
[occt.git] / src / AIS / AIS_LengthDimension.cxx
1 // Created on: 1996-12-05
2 // Created by: Arnaud BOUZY/Odile Olivier
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2013 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <AIS_LengthDimension.hxx>
18
19 #include <AIS.hxx>
20 #include <BRep_Tool.hxx>
21 #include <BRepAdaptor_Curve.hxx>
22 #include <BRepLib_MakeVertex.hxx>
23 #include <BRepTopAdaptor_FClass2d.hxx>
24 #include <BRepTools.hxx>
25 #include <ElCLib.hxx>
26 #include <ElSLib.hxx>
27 #include <gce_MakeDir.hxx>
28 #include <gce_MakePln.hxx>
29 #include <GeomAPI_ExtremaCurveCurve.hxx>
30 #include <GeomAPI_ExtremaCurveSurface.hxx>
31 #include <GeomAPI_ExtremaSurfaceSurface.hxx>
32 #include <Geom_Curve.hxx>
33 #include <Geom_Line.hxx>
34 #include <TopExp.hxx>
35 #include <TopExp_Explorer.hxx>
36
37
38 //=======================================================================
39 //function : Constructor
40 //purpose  : Dimension between two faces
41 //=======================================================================
42 AIS_LengthDimension::AIS_LengthDimension (const TopoDS_Face& theFirstFace,
43                                           const TopoDS_Face& theSecondFace)
44 : AIS_Dimension (AIS_KOD_LENGTH)
45 {
46   SetMeasuredGeometry (theFirstFace, theSecondFace);
47   SetFlyout (15.0);
48 }
49
50 //=======================================================================
51 //function : Constructor
52 //purpose  : Dimension between two shape
53 //=======================================================================
54 AIS_LengthDimension::AIS_LengthDimension (const TopoDS_Face& theFace,
55                                           const TopoDS_Edge& theEdge)
56 : AIS_Dimension (AIS_KOD_LENGTH)
57 {
58   SetMeasuredGeometry (theFace, theEdge);
59   SetFlyout (15.0);
60 }
61
62 //=======================================================================
63 //function : Constructor
64 //purpose  : Dimension between two points
65 //=======================================================================
66 AIS_LengthDimension::AIS_LengthDimension (const gp_Pnt& theFirstPoint,
67                                           const gp_Pnt& theSecondPoint,
68                                           const gp_Pln& thePlane)
69 : AIS_Dimension (AIS_KOD_LENGTH)
70 {
71   SetMeasuredGeometry (theFirstPoint, theSecondPoint, thePlane);
72   SetFlyout (15.0);
73 }
74
75 //=======================================================================
76 //function : Constructor
77 //purpose  : Dimension between two shape
78 //=======================================================================
79 AIS_LengthDimension::AIS_LengthDimension (const TopoDS_Shape& theFirstShape,
80                                           const TopoDS_Shape& theSecondShape,
81                                           const gp_Pln& thePlane)
82 : AIS_Dimension (AIS_KOD_LENGTH)
83 {
84   SetCustomPlane (thePlane);
85   SetMeasuredShapes (theFirstShape, theSecondShape);
86   SetFlyout (15.0);
87 }
88
89 //=======================================================================
90 //function : Constructor
91 //purpose  : Dimension of one edge
92 //=======================================================================
93 AIS_LengthDimension::AIS_LengthDimension (const TopoDS_Edge& theEdge,
94                                           const gp_Pln& thePlane)
95 : AIS_Dimension (AIS_KOD_LENGTH)
96 {
97   SetMeasuredGeometry (theEdge, thePlane);
98   SetFlyout (15.0);
99 }
100
101 //=======================================================================
102 //function : SetMeasuredGeometry
103 //purpose  : 
104 //=======================================================================
105 void AIS_LengthDimension::SetMeasuredGeometry (const gp_Pnt& theFirstPoint,
106                                                const gp_Pnt& theSecondPoint,
107                                                const gp_Pln& thePlane)
108 {
109   myFirstPoint      = theFirstPoint;
110   mySecondPoint     = theSecondPoint;
111   myFirstShape      = BRepLib_MakeVertex (myFirstPoint);
112   mySecondShape     = BRepLib_MakeVertex (mySecondPoint);
113   myGeometryType    = GeometryType_Points;
114   SetCustomPlane (thePlane);
115   myIsGeometryValid = IsValidPoints (theFirstPoint, theSecondPoint);
116
117   SetToUpdate();
118 }
119
120 //=======================================================================
121 //function : SetMeasuredGeometry
122 //purpose  : 
123 //=======================================================================
124 void AIS_LengthDimension::SetMeasuredGeometry (const TopoDS_Edge& theEdge,
125                                                const gp_Pln& thePlane)
126 {
127   myFirstShape      = theEdge;
128   mySecondShape     = TopoDS_Shape();
129   myGeometryType    = GeometryType_Edge;
130   SetCustomPlane (thePlane);
131   myIsGeometryValid = InitOneShapePoints (myFirstShape);
132
133   SetToUpdate();
134 }
135
136 //=======================================================================
137 //function : SetMeasuredGeometry
138 //purpose  : 
139 //=======================================================================
140 void AIS_LengthDimension::SetMeasuredGeometry (const TopoDS_Face& theFirstFace,
141                                                const TopoDS_Face& theSecondFace)
142 {
143   SetMeasuredShapes (theFirstFace, theSecondFace);
144 }
145
146 //=======================================================================
147 //function : SetMeasuredGeometry
148 //purpose  : 
149 //=======================================================================
150 void AIS_LengthDimension::SetMeasuredGeometry (const TopoDS_Face& theFace,
151                                                const TopoDS_Edge& theEdge)
152 {
153   SetMeasuredShapes (theFace, theEdge);
154 }
155
156 //=======================================================================
157 //function : SetMeasuredShapes
158 //purpose  : 
159 //=======================================================================
160 void AIS_LengthDimension::SetMeasuredShapes (const TopoDS_Shape& theFirstShape,
161                                              const TopoDS_Shape& theSecondShape)
162 {
163   gp_Pln aComputedPlane;
164   Standard_Boolean isPlaneReturned = Standard_False;
165
166   myFirstShape      = theFirstShape;
167   mySecondShape     = theSecondShape;
168   myIsGeometryValid = InitTwoShapesPoints (myFirstShape, mySecondShape, aComputedPlane, isPlaneReturned);
169
170   if (myIsGeometryValid && !myIsPlaneCustom)
171   {
172     if (isPlaneReturned)
173     {
174       myPlane = aComputedPlane;
175     }
176     else
177     {
178       myIsGeometryValid = Standard_False;
179     }
180   }
181
182   SetToUpdate();
183 }
184
185 //=======================================================================
186 //function : CheckPlane
187 //purpose  : 
188 //=======================================================================
189 Standard_Boolean AIS_LengthDimension::CheckPlane (const gp_Pln& thePlane) const
190 {
191   if (!thePlane.Contains (myFirstPoint, Precision::Confusion()) &&
192       !thePlane.Contains (mySecondPoint, Precision::Confusion()))
193   {
194     return Standard_False;
195   }
196
197   return Standard_True;
198 }
199
200 //=======================================================================
201 //function : ComputePlane
202 //purpose  : 
203 //=======================================================================
204 gp_Pln AIS_LengthDimension::ComputePlane (const gp_Dir& theAttachDir) const
205 {
206   if (!IsValidPoints (myFirstPoint, mySecondPoint))
207   {
208     return gp_Pln();
209   }
210
211   gp_Pnt aThirdPoint (myFirstPoint.Translated (gp_Vec(theAttachDir)));
212   gce_MakePln aPlaneConstrustor (myFirstPoint, mySecondPoint, aThirdPoint);
213   return aPlaneConstrustor.Value();
214 }
215
216 //=======================================================================
217 //function : GetModelUnits
218 //purpose  :
219 //=======================================================================
220 const TCollection_AsciiString& AIS_LengthDimension::GetModelUnits() const
221 {
222   return myDrawer->DimLengthModelUnits();
223 }
224
225 //=======================================================================
226 //function : GetDisplayUnits
227 //purpose  :
228 //=======================================================================
229 const TCollection_AsciiString& AIS_LengthDimension::GetDisplayUnits() const
230 {
231   return myDrawer->DimLengthDisplayUnits();
232 }
233
234 //=======================================================================
235 //function : SetModelUnits
236 //purpose  :
237 //=======================================================================
238 void AIS_LengthDimension::SetModelUnits (const TCollection_AsciiString& theUnits)
239 {
240   myDrawer->SetDimLengthModelUnits (theUnits);
241 }
242
243 //=======================================================================
244 //function : SetDisplayUnits
245 //purpose  :
246 //=======================================================================
247 void AIS_LengthDimension::SetDisplayUnits (const TCollection_AsciiString& theUnits)
248 {
249   myDrawer->SetDimLengthDisplayUnits (theUnits);
250 }
251
252 //=======================================================================
253 //function : ComputeValue
254 //purpose  : 
255 //=======================================================================
256 Standard_Real AIS_LengthDimension::ComputeValue() const
257 {
258   return IsValid() ? myFirstPoint.Distance (mySecondPoint) : 0.0;
259 }
260
261 //=======================================================================
262 //function : Compute
263 //purpose  : 
264 //=======================================================================
265 void AIS_LengthDimension::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePM*/,
266                                    const Handle(Prs3d_Presentation)& thePresentation,
267                                    const Standard_Integer theMode)
268 {
269   thePresentation->Clear();
270   mySelectionGeom.Clear (theMode);
271
272   if (!IsValid())
273   {
274     return;
275   }
276
277   DrawLinearDimension (thePresentation, theMode, myFirstPoint, mySecondPoint);
278 }
279
280 //=======================================================================
281 //function : ComputeFlyoutSelection
282 //purpose  : 
283 //=======================================================================
284 void AIS_LengthDimension::ComputeFlyoutSelection (const Handle(SelectMgr_Selection)& theSelection,
285                                                   const Handle(SelectMgr_EntityOwner)& theEntityOwner)
286 {
287   if (!IsValid())
288   {
289     return;
290   }
291
292   ComputeLinearFlyouts (theSelection, theEntityOwner, myFirstPoint, mySecondPoint);
293 }
294
295 //=======================================================================
296 //function : IsValidPoints
297 //purpose  :
298 //=======================================================================
299 Standard_Boolean AIS_LengthDimension::IsValidPoints (const gp_Pnt& theFirstPoint,
300                                                      const gp_Pnt& theSecondPoint) const
301 {
302   return theFirstPoint.Distance (theSecondPoint) > Precision::Confusion();
303 }
304
305 //=======================================================================
306 //function : InitTwoEdgesLength
307 //purpose  : Initialization of dimension between two linear edges
308 //=======================================================================
309 Standard_Boolean AIS_LengthDimension::InitTwoEdgesLength (const TopoDS_Edge& theFirstEdge,
310                                                           const TopoDS_Edge& theSecondEdge,
311                                                           gp_Dir& theDirAttach)
312 {
313   BRepAdaptor_Curve aFirstCurveAdapt (theFirstEdge);
314   if (aFirstCurveAdapt.GetType() != GeomAbs_Line)
315   {
316     return Standard_False;
317   }
318
319   BRepAdaptor_Curve aSecondCurveAdapt (theSecondEdge);
320   if (aSecondCurveAdapt.GetType() != GeomAbs_Line)
321   {
322     return Standard_False;
323   }
324
325   Handle(Geom_Curve) aFirstCurve;
326   Handle(Geom_Curve) aSecondCurve;
327
328   gp_Pnt aPoint11 (gp::Origin());
329   gp_Pnt aPoint12 (gp::Origin());
330   gp_Pnt aPoint21 (gp::Origin());
331   gp_Pnt aPoint22 (gp::Origin());
332   Standard_Boolean isFirstInfinite  = Standard_False;
333   Standard_Boolean isSecondInfinite = Standard_False;
334
335   if (!AIS::ComputeGeometry (theFirstEdge, theSecondEdge,
336                              aFirstCurve, aSecondCurve,
337                              aPoint11, aPoint12,
338                              aPoint21, aPoint22,
339                              isFirstInfinite,
340                              isSecondInfinite))
341   {
342     return Standard_False;
343   }
344
345   const Handle(Geom_Line) aFirstLine = Handle(Geom_Line)::DownCast (aFirstCurve);
346   const Handle(Geom_Line) aSecondLine = Handle(Geom_Line)::DownCast (aSecondCurve);
347
348   if (!aFirstLine->Lin().Direction().IsParallel (aSecondLine->Lin().Direction(),Precision::Angular()))
349   {
350     return Standard_False;
351   }
352
353   theDirAttach = aFirstLine->Lin().Direction();
354
355   gp_Pnt aPoint;
356
357   if (!isFirstInfinite)
358   {
359     if (AIS::Nearest (aSecondCurve, aPoint11, aPoint21, aPoint22, aPoint))
360     {
361       myFirstPoint = aPoint11;
362       mySecondPoint = aPoint;
363       return IsValidPoints (myFirstPoint, mySecondPoint);
364     }
365     else if (AIS::Nearest (aSecondCurve, aPoint12, aPoint21, aPoint22, aPoint))
366     {
367       myFirstPoint = aPoint12;
368       mySecondPoint = aPoint;
369       return IsValidPoints (myFirstPoint, mySecondPoint);
370     }
371   }
372
373   if (!isSecondInfinite)
374   {
375     if (AIS::Nearest (aFirstCurve, aPoint21, aPoint11, aPoint12, aPoint))
376     {
377       myFirstPoint = aPoint;
378       mySecondPoint = aPoint21;
379       return IsValidPoints (myFirstPoint, mySecondPoint);
380     }
381     if (AIS::Nearest (aFirstCurve, aPoint22, aPoint11, aPoint12, aPoint))
382     {
383       myFirstPoint = aPoint;
384       mySecondPoint = aPoint22;
385       return IsValidPoints (myFirstPoint, mySecondPoint);
386     }
387   }
388
389   GeomAPI_ExtremaCurveCurve anExtrema (aFirstCurve, aSecondCurve);
390   anExtrema.NearestPoints (myFirstPoint, mySecondPoint);
391   return IsValidPoints (myFirstPoint, mySecondPoint);
392 }
393
394 //=======================================================================
395 //function : InitEdgeVertexLength
396 //purpose  : for first edge and second vertex shapes
397 //=======================================================================
398 Standard_Boolean AIS_LengthDimension::InitEdgeVertexLength (const TopoDS_Edge& theEdge,
399                                                             const TopoDS_Vertex& theVertex,
400                                                             gp_Dir& theEdgeDir,
401                                                             Standard_Boolean isInfinite)
402 {
403   gp_Pnt anEdgePoint1 (gp::Origin());
404   gp_Pnt anEdgePoint2 (gp::Origin());
405   Handle(Geom_Curve) aCurve;
406
407   if (!AIS::ComputeGeometry (theEdge, aCurve, anEdgePoint1, anEdgePoint2, isInfinite))
408   {
409     return Standard_False;
410   }
411
412   myFirstPoint = BRep_Tool::Pnt (theVertex);
413
414   Handle(Geom_Line) aGeomLine (Handle(Geom_Line)::DownCast (aCurve));
415   const gp_Lin& aLin = aGeomLine->Lin();
416
417   // Get direction of edge to build plane automatically.
418   theEdgeDir = aLin.Direction();
419
420   mySecondPoint = AIS::Nearest (aLin, myFirstPoint);
421
422   return IsValidPoints (myFirstPoint, mySecondPoint);
423 }
424
425 //=======================================================================
426 //function : InitEdgeFaceLength
427 //purpose  : 
428 //=======================================================================
429 Standard_Boolean AIS_LengthDimension::InitEdgeFaceLength (const TopoDS_Edge& theEdge,
430                                                           const TopoDS_Face& theFace,
431                                                           gp_Dir& theEdgeDir)
432 {
433   Handle(Geom_Curve) aCurve;
434   gp_Pnt aFirstPoint, aSecondPoint;
435   Standard_Boolean isInfinite = Standard_False;
436
437   if (!AIS::ComputeGeometry (theEdge, aCurve, aFirstPoint, aSecondPoint, isInfinite))
438   {
439     return Standard_False;
440   }
441   theEdgeDir = gce_MakeDir (aFirstPoint, aSecondPoint);
442   gp_Pln aPlane;
443   Handle(Geom_Surface) aSurface;
444   AIS_KindOfSurface aSurfType;
445   Standard_Real anOffset;
446
447   if (!AIS::GetPlaneFromFace (theFace, aPlane, aSurface, aSurfType, anOffset))
448   {
449     return Standard_False;
450   }
451
452   GeomAPI_ExtremaCurveSurface aDistAdaptor (aCurve, aSurface);
453
454   aDistAdaptor.NearestPoints (myFirstPoint, mySecondPoint);
455
456   return IsValidPoints (myFirstPoint, mySecondPoint);
457 }
458
459 //=======================================================================
460 //function : InitTwoShapesPoints
461 //purpose  : Initialization of two points where dimension layouts
462 //           will be attached
463 //=======================================================================
464 Standard_Boolean AIS_LengthDimension::InitTwoShapesPoints (const TopoDS_Shape& theFirstShape,
465                                                            const TopoDS_Shape& theSecondShape,
466                                                            gp_Pln& theComputedPlane,
467                                                            Standard_Boolean& theIsPlaneComputed)
468 {
469   theIsPlaneComputed = Standard_False;
470   gp_Dir aDirAttach;
471   Standard_Boolean isInfinite = Standard_False;
472   Standard_Boolean isSuccess  = Standard_False;
473   switch (theFirstShape.ShapeType())
474   {
475     case TopAbs_FACE:
476     {
477       // Initialization for face
478       gp_Pln aFirstPlane;
479       Handle(Geom_Surface) aFirstSurface;
480       AIS_KindOfSurface aFirstSurfKind;
481       Standard_Real aFirstOffset;
482
483       TopoDS_Face aFirstFace = TopoDS::Face (theFirstShape);
484
485       AIS::InitFaceLength (TopoDS::Face (theFirstShape),
486                            aFirstPlane,
487                            aFirstSurface,
488                            aFirstSurfKind,
489                            aFirstOffset);
490
491       if (theSecondShape.ShapeType() == TopAbs_FACE)
492       {
493         // Initialization for face
494         myGeometryType = GeometryType_Faces;
495         gp_Pln aSecondPlane;
496         Handle(Geom_Surface) aSecondSurface;
497         AIS_KindOfSurface aSecondSurfKind;
498         Standard_Real aSecondOffset;
499
500         TopoDS_Face aSecondFace = TopoDS::Face (theSecondShape);
501
502         AIS::InitFaceLength (aSecondFace,
503                              aSecondPlane,
504                              aSecondSurface,
505                              aSecondSurfKind,
506                              aSecondOffset);
507
508         if (aFirstSurfKind == AIS_KOS_Plane)
509         {
510           if (!aFirstPlane.Axis().Direction().IsParallel (aSecondPlane.Axis().Direction(), Precision::Angular()))
511           {
512             return Standard_False;
513           }
514
515           TopExp_Explorer anExplorer (theFirstShape, TopAbs_VERTEX);
516
517           // In case of infinite planes
518           if (!anExplorer.More())
519           {
520             myFirstPoint = aFirstPlane.Location();
521           }
522           else
523           {
524             myFirstPoint = BRep_Tool::Pnt (TopoDS::Vertex (anExplorer.Current()));
525           }
526
527           mySecondPoint = AIS::ProjectPointOnPlane (myFirstPoint, aSecondPlane);
528
529           Quantity_Parameter anU, aV;
530           ElSLib::Parameters (aSecondPlane, mySecondPoint, anU, aV);
531
532           BRepTopAdaptor_FClass2d aClassifier (aSecondFace, Precision::Confusion());
533           TopAbs_State aState = aClassifier.Perform (gp_Pnt2d (anU, aV), Standard_False);
534
535           if (aState == TopAbs_OUT || aState == TopAbs_UNKNOWN)
536           {
537             mySecondPoint = AIS::Nearest (aSecondFace, myFirstPoint);
538           }
539
540           isSuccess = IsValidPoints (myFirstPoint, mySecondPoint);
541           if (isSuccess)
542           {
543             theComputedPlane = ComputePlane (aFirstPlane.Position().XDirection());
544             theIsPlaneComputed = Standard_True;
545           }
546         }
547         else // curvilinear faces
548         {
549           Standard_Real aU1Min, aV1Min, aU1Max, aV1Max;
550           Standard_Real aU2Min, aV2Min, aU2Max, aV2Max;
551           BRepTools::UVBounds (aFirstFace, aU1Min, aU1Max, aV1Min,  aV1Max);
552           BRepTools::UVBounds (aSecondFace, aU2Min, aU2Max, aV2Min, aV2Max);
553
554           GeomAPI_ExtremaSurfaceSurface anExtrema (aFirstSurface, aSecondSurface,
555                                                    aU1Min, aU1Max, aV1Min, aV1Max,
556                                                    aU2Min, aU2Max, aV2Min, aV2Max);
557
558           Standard_Real aU1, aV1, aU2, aV2;
559           anExtrema.LowerDistanceParameters (aU1, aV1, aU2, aV2);
560           myFirstPoint = BRep_Tool::Surface (aFirstFace)->Value (aU1, aV1);
561           mySecondPoint = BRep_Tool::Surface (aSecondFace)->Value (aU2, aV2);
562
563           // Adjust automatic plane
564           gp_Ax2 aLocalAxes (myFirstPoint, gce_MakeDir (myFirstPoint, mySecondPoint));
565           aDirAttach = gce_MakeDir (aLocalAxes.XDirection ());
566
567           // Check points
568           isSuccess = IsValidPoints (myFirstPoint, mySecondPoint);
569           if (isSuccess)
570           {
571             theComputedPlane = ComputePlane (aDirAttach);
572             theIsPlaneComputed = Standard_True;
573           }
574         }
575
576         return isSuccess && IsValidPoints (myFirstPoint, mySecondPoint);
577       }
578       else if (theFirstShape.ShapeType() == TopAbs_EDGE)
579       {
580         myGeometryType = GeometryType_EdgeFace;
581         isSuccess = InitEdgeFaceLength (TopoDS::Edge (theFirstShape),
582                                         TopoDS::Face (theSecondShape),
583                                         aDirAttach);
584
585         if (isSuccess)
586         {
587           theComputedPlane = ComputePlane (aDirAttach);
588           theIsPlaneComputed = Standard_True;
589         }
590
591         return isSuccess;
592       }
593     }
594     break;
595
596     case TopAbs_EDGE:
597     {
598       if (theSecondShape.ShapeType() == TopAbs_VERTEX)
599       {
600         myGeometryType = GeometryType_EdgeVertex;
601         isSuccess = InitEdgeVertexLength (TopoDS::Edge (theFirstShape),
602                                           TopoDS::Vertex (theSecondShape),
603                                           aDirAttach,
604                                           isInfinite);
605
606         if (isSuccess)
607         {
608           theComputedPlane = ComputePlane (aDirAttach);
609           theIsPlaneComputed = Standard_True;
610         }
611
612         return isSuccess;
613       }
614       else if (theSecondShape.ShapeType() == TopAbs_EDGE)
615       {
616         myGeometryType = GeometryType_Edges;
617         isSuccess = InitTwoEdgesLength (TopoDS::Edge (theFirstShape),
618                                         TopoDS::Edge (theSecondShape),
619                                         aDirAttach);
620
621         if (isSuccess)
622         {
623           theComputedPlane = ComputePlane (aDirAttach);
624           theIsPlaneComputed = Standard_True;
625         }
626
627         return isSuccess;
628       }
629     }
630     break;
631
632     case TopAbs_VERTEX:
633     {
634       if (theSecondShape.ShapeType() == TopAbs_VERTEX)
635       {
636         myGeometryType = GeometryType_Points;
637         myFirstPoint  = BRep_Tool::Pnt (TopoDS::Vertex (theFirstShape));
638         mySecondPoint = BRep_Tool::Pnt (TopoDS::Vertex (theSecondShape));
639
640         return IsValidPoints (myFirstPoint, mySecondPoint);
641       }
642       else if (theSecondShape.ShapeType() == TopAbs_EDGE)
643       {
644         myGeometryType = GeometryType_EdgeVertex;
645         Standard_Boolean isSuccess =  InitEdgeVertexLength (TopoDS::Edge(theSecondShape),
646                                                             TopoDS::Vertex(theFirstShape),
647                                                             aDirAttach,
648                                                             isInfinite);
649         if (isSuccess)
650         {
651           theComputedPlane = ComputePlane (aDirAttach);
652           theIsPlaneComputed = Standard_True;
653         }
654
655         return isSuccess;
656       }
657     }
658     break;
659
660     case TopAbs_COMPOUND:
661     case TopAbs_COMPSOLID:
662     case TopAbs_SOLID:
663     case TopAbs_SHELL:
664     case TopAbs_WIRE:
665     case TopAbs_SHAPE:
666       break;
667   }
668
669   return Standard_False;
670 }
671
672 //=======================================================================
673 //function : InitOneShapePoints
674 //purpose  : Initialization of two points where dimension layouts
675 //           will be attached
676 // Attention: 1) <theShape> can be only the edge in currect implementation
677 //            2) No length for infinite edge
678 //=======================================================================
679 Standard_Boolean AIS_LengthDimension::InitOneShapePoints (const TopoDS_Shape& theShape)
680 {
681   if (theShape.ShapeType() != TopAbs_EDGE)
682   {
683     return Standard_False;
684   }
685
686   TopoDS_Edge anEdge = TopoDS::Edge (theShape);
687
688   BRepAdaptor_Curve aBrepCurve(anEdge);
689   Standard_Real aFirst = aBrepCurve.FirstParameter();
690   Standard_Real aLast  = aBrepCurve.LastParameter();
691
692   if (aBrepCurve.GetType() != GeomAbs_Line)
693   {
694     return Standard_False;
695   }
696
697   Standard_Boolean isInfinite = (Precision::IsInfinite (aFirst) || Precision::IsInfinite (aLast));
698   if (isInfinite)
699   {
700     return Standard_False;
701   }
702
703   myFirstPoint  = aBrepCurve.Value (aBrepCurve.FirstParameter());
704   mySecondPoint = aBrepCurve.Value (aBrepCurve.LastParameter());
705
706   return IsValidPoints (myFirstPoint, mySecondPoint);
707 }
708
709 //=======================================================================
710 //function : GetTextPosition
711 //purpose  : 
712 //=======================================================================
713 const gp_Pnt AIS_LengthDimension::GetTextPosition() const
714 {
715   if (IsTextPositionCustom())
716   {
717     return myFixedTextPosition;
718   }
719
720   // Counts text position according to the dimension parameters
721   return GetTextPositionForLinear (myFirstPoint, mySecondPoint);
722 }
723
724 //=======================================================================
725 //function : SetTextPosition
726 //purpose  : 
727 //=======================================================================
728 void AIS_LengthDimension::SetTextPosition (const gp_Pnt& theTextPos)
729 {
730   if (!IsValid())
731   {
732     return;
733   }
734
735   myIsTextPositionFixed = Standard_True;
736   myFixedTextPosition = theTextPos;
737
738   SetToUpdate();
739 }