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