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