0023024: Update headers of OCCT files
[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-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21
22 #define BUC60915        //GG 05/06/01 Enable to compute the requested arrow size
23 //                      if any in all dimensions.
24
25 #include <Standard_NotImplemented.hxx>
26
27 #include <AIS_LengthDimension.ixx>
28
29 #include <AIS.hxx>
30 #include <AIS_DimensionOwner.hxx>
31 #include <AIS_Drawer.hxx>
32
33 #include <BRepAdaptor_Curve.hxx>
34 #include <BRepAdaptor_Surface.hxx>
35 #include <BRep_Tool.hxx>
36
37 #include <DsgPrs.hxx>
38 #include <DsgPrs_LengthPresentation.hxx>
39
40 #include <ElCLib.hxx>
41 #include <ElSLib.hxx>
42
43 #include <Geom_Circle.hxx>
44 #include <Geom_Curve.hxx>
45 #include <Geom_TrimmedCurve.hxx>
46 #include <Geom_Line.hxx>
47 #include <Geom_Plane.hxx>
48 #include <Geom_OffsetSurface.hxx>
49
50 #include <Precision.hxx>
51
52 #include <ProjLib.hxx>
53
54 #include <Prs3d_ArrowAspect.hxx>
55 #include <Prs3d_Drawer.hxx>
56 #include <Prs3d_LengthAspect.hxx>
57 #include <Prs3d_LineAspect.hxx>
58
59 #include <Select3D_SensitiveBox.hxx>
60 #include <Select3D_SensitiveSegment.hxx>
61 #include <Select3D_SensitiveCurve.hxx>
62 #include <SelectMgr_EntityOwner.hxx>
63
64 #include <Standard_DomainError.hxx>
65
66 #include <StdPrs_WFDeflectionShape.hxx>
67
68 #include <TCollection_AsciiString.hxx>
69 #include <TCollection_ExtendedString.hxx>
70
71 #include <TopExp.hxx>
72 #include <TopExp_Explorer.hxx>
73 #include <TopoDS.hxx>
74
75 #include <gce_MakeDir.hxx>
76 #include <gce_MakeLin.hxx>
77
78 #include <gp_Ax1.hxx>
79 #include <gp_Ax2.hxx>
80 #include <gp_Dir.hxx>
81 #include <gp_Lin.hxx>
82 #include <gp_Pln.hxx>
83 #include <gp_Pnt.hxx>
84 #include <gp_Pnt2d.hxx>
85
86 #include <Prs3d_AngleAspect.hxx>
87
88 #include <BRepGProp_Face.hxx>
89
90
91 //=======================================================================
92 //function : Constructor
93 //purpose  : TwoFacesLength dimension
94 //=======================================================================
95
96 AIS_LengthDimension::AIS_LengthDimension (const TopoDS_Face&  aFirstFace, 
97                                           const TopoDS_Face&  aSecondFace,
98                                           const Standard_Real aVal,
99                                           const TCollection_ExtendedString& aText)
100 :AIS_Relation(),
101  myNbShape(2)
102 {
103   SetFirstShape( aFirstFace );
104   SetSecondShape( aSecondFace );
105   myVal = aVal;
106
107   myText = aText;
108   mySymbolPrs = DsgPrs_AS_BOTHAR;
109   myAutomaticPosition = Standard_True;
110
111   myArrowSize = myVal / 10.;
112 }
113
114 //=======================================================================
115 //function : Constructor
116 //purpose  : TwoFacesLength dimension  (with position and text)
117 //=======================================================================
118
119 AIS_LengthDimension::AIS_LengthDimension(const TopoDS_Face& aFirstFace,
120                                          const TopoDS_Face& aSecondFace,
121                                          const Standard_Real aVal, 
122                                          const TCollection_ExtendedString& aText,
123                                          const gp_Pnt& aPosition,
124                                          const DsgPrs_ArrowSide aSymbolPrs,
125                                          const Standard_Real anArrowSize)
126 :AIS_Relation(),
127  myNbShape(2)
128 {
129   SetFirstShape( aFirstFace );
130   SetSecondShape( aSecondFace );
131   myVal = aVal;
132
133   myText = aText;
134   mySymbolPrs = aSymbolPrs;
135   myAutomaticPosition = Standard_False;
136 #ifdef BUC60915
137   SetArrowSize( anArrowSize );
138 #else
139   myArrowSize = anArrowSize;
140 #endif
141   myPosition = aPosition;
142 }
143
144
145
146 //=======================================================================
147 //function : AIS_LengthDimension
148 //purpose  : Distance Face - Edge for chamfer 3D
149 //=======================================================================
150
151 AIS_LengthDimension::AIS_LengthDimension (const TopoDS_Face& Face,const TopoDS_Edge& Edge,const Standard_Real Val,const TCollection_ExtendedString& Text)
152
153 :AIS_Relation (),
154  myNbShape    (2)
155 {
156   SetFirstShape  (Face);
157   SetSecondShape (Edge);
158   myText = Text;
159   myVal = Val;
160   mySymbolPrs = DsgPrs_AS_BOTHAR;
161   myAutomaticPosition = Standard_True;
162   myArrowSize = myVal/10.0;
163 }
164
165
166
167 //=======================================================================
168 //function : Constructor
169 //purpose  : TwoEdgesLength dimension or OneEdgeOneVertexLength dimension or TwoVerticesLength dimension
170 //=======================================================================
171
172 AIS_LengthDimension::AIS_LengthDimension(const TopoDS_Shape& aFShape,
173                                          const TopoDS_Shape& aSShape,
174                                          const Handle(Geom_Plane)& aPlane,
175                                          const Standard_Real aVal,
176                                          const TCollection_ExtendedString& aText)
177 :AIS_Relation(),
178  myNbShape(2),
179  myTypeDist(AIS_TOD_Unknown)
180 {
181   myFShape = aFShape;
182   mySShape = aSShape;
183   myVal = aVal;
184   myText = aText;
185   mySymbolPrs = DsgPrs_AS_BOTHAR;
186   myAutomaticPosition = Standard_True;
187   myPlane =aPlane;
188   myArrowSize = myVal / 10.;
189 }
190
191 //=======================================================================
192 //function : Constructor
193 //purpose  : TwoEdgesLength dimension or OneEdgeOneVertexLength dimension or TwoVerticesLength dimension
194 //=======================================================================
195
196 AIS_LengthDimension::AIS_LengthDimension(const TopoDS_Shape& aFShape, 
197                                          const TopoDS_Shape& aSShape, 
198                                          const Handle(Geom_Plane)& aPlane, 
199                                          const Standard_Real aVal, 
200                                          const TCollection_ExtendedString& aText, 
201                                          const gp_Pnt& aPosition,
202                                          const DsgPrs_ArrowSide aSymbolPrs,
203                                          const AIS_TypeOfDist aTypeDist, 
204                                          const Standard_Real anArrowSize)
205 :AIS_Relation(),
206  myNbShape(2),
207  myTypeDist(aTypeDist)
208 {
209   myFShape = aFShape;
210   mySShape = aSShape;
211   myVal = aVal;
212   myPlane = aPlane;
213   myText = aText;
214   mySymbolPrs = aSymbolPrs;
215   myAutomaticPosition = Standard_False;
216 #ifdef BUC60915
217   SetArrowSize( anArrowSize );
218 #else
219   myArrowSize = anArrowSize;
220 #endif
221   myPosition = aPosition;
222 }
223
224
225
226 //=======================================================================
227 //function : Compute
228 //purpose  : 
229 //=======================================================================
230
231 void AIS_LengthDimension::Compute(const Handle(PrsMgr_PresentationManager3d)&,
232                                   const Handle(Prs3d_Presentation)& aPresentation,
233                                   const Standard_Integer)
234 {
235   aPresentation->Clear();
236
237   if (myNbShape == 1) {
238     switch (myFShape.ShapeType()) {
239     case TopAbs_FACE:
240       {
241         // case length on a face
242         ComputeOneFaceLength(aPresentation);
243       }
244       break;
245     case TopAbs_EDGE:
246       {
247         // case length of an edge
248         ComputeOneEdgeLength(aPresentation);
249       }
250       break;
251     default:
252       break;
253     }
254   }
255   else if (myNbShape == 2) {
256     switch (myFShape.ShapeType()) {
257     case TopAbs_FACE:
258       {
259         if (mySShape.ShapeType () == TopAbs_FACE) {
260           // case length between two faces
261           ComputeTwoFacesLength(aPresentation);
262         }
263         else if (mySShape.ShapeType () == TopAbs_EDGE) {
264           ComputeEdgeFaceLength (aPresentation);
265         }
266       }
267       break;
268     case TopAbs_EDGE:
269       {
270         if (mySShape.ShapeType() == TopAbs_VERTEX) {      
271 #ifdef BUC60915
272           if( !myArrowSizeIsDefined ) 
273 #endif
274             myArrowSize = Abs(myVal)/100.;
275           ComputeOneEdgeOneVertexLength( aPresentation,
276                                         myDrawer,
277                                         myText,
278                                         myArrowSize,
279                                         myFShape,
280                                         mySShape,
281                                         myPlane,
282                                         myAutomaticPosition,
283                                         myIsSetBndBox,
284                                         myBndBox,
285                                         myExtShape,
286                                         myVal,
287                                         myDirAttach,
288                                         myPosition,
289                                         myFAttach,
290                                         mySAttach,
291                                         mySymbolPrs );
292         }
293         else if (mySShape.ShapeType() == TopAbs_EDGE) {
294           // case length between two edges
295 #ifdef BUC60915
296           if( !myArrowSizeIsDefined ) 
297 #endif
298             myArrowSize = Abs(myVal)/100.;
299           ComputeTwoEdgesLength( aPresentation,
300                                 myDrawer,
301                                 myText,
302                                 myArrowSize,
303                                 TopoDS::Edge( myFShape ),
304                                 TopoDS::Edge( mySShape ),
305                                 myPlane,
306                                 myAutomaticPosition,
307                                 myIsSetBndBox,
308                                 myBndBox,
309                                 myExtShape,
310                                 myVal,
311                                 myDirAttach,
312                                 myPosition,
313                                 myFAttach,
314                                 mySAttach,
315                                 mySymbolPrs );
316         }
317       }
318       break;
319
320     case TopAbs_VERTEX:
321       {
322         if (mySShape.ShapeType() == TopAbs_VERTEX) {
323 #ifdef BUC60915
324           if( !myArrowSizeIsDefined ) 
325 #endif
326             myArrowSize = Abs(myVal)/100.;
327           ComputeTwoVerticesLength( aPresentation,
328                                    myDrawer,
329                                    myText,
330                                    myArrowSize,
331                                    TopoDS::Vertex( myFShape ),
332                                    TopoDS::Vertex( mySShape ),
333                                    myPlane,
334                                    myAutomaticPosition,
335                                    myIsSetBndBox,
336                                    myBndBox,
337                                    myTypeDist,
338                                    myExtShape,
339                                    myVal,
340                                    myDirAttach,
341                                    myPosition,
342                                    myFAttach,
343                                    mySAttach,
344                                    mySymbolPrs );
345         }
346         else if (mySShape.ShapeType() == TopAbs_EDGE) {
347 #ifdef BUC60915
348           if( !myArrowSizeIsDefined ) 
349 #endif
350             myArrowSize = Abs(myVal)/100.;
351           ComputeOneEdgeOneVertexLength( aPresentation,
352                                         myDrawer,
353                                         myText,
354                                         myArrowSize,
355                                         myFShape,
356                                         mySShape,
357                                         myPlane,
358                                         myAutomaticPosition,
359                                         myIsSetBndBox,
360                                         myBndBox,
361                                         myExtShape,
362                                         myVal,
363                                         myDirAttach,
364                                         myPosition,
365                                         myFAttach,
366                                         mySAttach,
367                                         mySymbolPrs );
368         }
369       }
370       break;
371     default:
372       break;
373     }
374   }
375
376 }
377
378 //=======================================================================
379 //function : Compute
380 //purpose  : to avoid warning
381 //=======================================================================
382
383 void AIS_LengthDimension::Compute(const Handle(Prs3d_Projector)& aProjector, 
384                                   const Handle(Prs3d_Presentation)& aPresentation)
385 {
386 // Standard_NotImplemented::Raise("AIS_LengthDimension::Compute(const Handle(Prs3d_Projector)&,const Handle(Prs3d_Presentation)&)");
387  PrsMgr_PresentableObject::Compute( aProjector , aPresentation ) ;
388 }
389
390 //=======================================================================
391 //function : Compute
392 //purpose  : to avoid warning
393 //=======================================================================
394
395 void AIS_LengthDimension::Compute(const Handle(PrsMgr_PresentationManager2d)& aPresentationManager2d,
396                                   const Handle(Graphic2d_GraphicObject)& aGraphicObject,
397                                   const Standard_Integer anInteger)
398 {
399 // Standard_NotImplemented::Raise("AIS_LengthDimension::Compute(const Handle(PrsMgr_PresentationManager2d)&,const Handle(Graphic2d_GraphicObject)&,const Standard_Integer)");
400  PrsMgr_PresentableObject::Compute( aPresentationManager2d ,aGraphicObject,anInteger) ;
401 }
402
403 void AIS_LengthDimension::Compute(const Handle_Prs3d_Projector& aProjector, const Handle_Geom_Transformation& aTransformation, const Handle_Prs3d_Presentation& aPresentation)
404 {
405 // Standard_NotImplemented::Raise("AIS_LengthDimension::Compute(const Handle_Prs3d_Projector&, const Handle_Geom_Transformation&, const Handle_Prs3d_Presentation&)");
406  PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation ) ;
407 }
408
409 //=======================================================================
410 //function : ComputeSelection
411 //purpose  : 
412 //=======================================================================
413
414 void AIS_LengthDimension::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
415                                            const Standard_Integer)
416 {
417   if (myFShape.IsNull() && mySShape.IsNull()) return;
418   if (myFShape.ShapeType() == TopAbs_FACE) ComputeFaceSelection(aSelection);
419   else ComputeEdgeVertexSelection(aSelection);
420
421   // Text
422   Handle( SelectMgr_EntityOwner ) own = new SelectMgr_EntityOwner( this, 7 );
423   Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6));
424   Handle( Select3D_SensitiveBox ) box = new Select3D_SensitiveBox( own,
425                                                                    myPosition.X(),
426                                                                    myPosition.Y(),
427                                                                    myPosition.Z(),
428                                                                    myPosition.X() + size,
429                                                                    myPosition.Y() + size,
430                                                                    myPosition.Z() + size);
431   aSelection->Add(box);
432 }
433
434
435 //=======================================================================
436 //function : ComputeOneFaceLength
437 //purpose  : 
438 //=======================================================================
439
440 void AIS_LengthDimension::ComputeOneFaceLength(const Handle(Prs3d_Presentation)&)
441 {
442   Standard_DomainError::Raise("AIS_LengthDimension::ComputeOneFaceLength : Not implemented");
443 }
444
445 //=======================================================================
446 //function : ComputeOneOneEdgeLength
447 //purpose  : 
448 //=======================================================================
449
450 void AIS_LengthDimension::ComputeOneEdgeLength(const Handle(Prs3d_Presentation)&)
451 {
452   Standard_DomainError::Raise("AIS_LengthDimension::ComputeOneEdgeLength : Not implemented");
453 }
454
455 //=======================================================================
456 //function : ComputeTwoFacesLength
457 //purpose  : 
458 //=======================================================================
459
460 void AIS_LengthDimension::ComputeTwoFacesLength( const Handle( Prs3d_Presentation )& aPresentation )
461 {
462   if (myFShape.ShapeType() == TopAbs_COMPOUND)  {                //rob debug from vbu?
463     TopExp_Explorer E (myFShape,TopAbs_FACE);
464     if (E.More())  SetFirstShape(E.Current());
465   }
466   if (mySShape.ShapeType() == TopAbs_COMPOUND)  {
467     TopExp_Explorer E (mySShape,TopAbs_FACE);
468     if (E.More())  SetSecondShape(E.Current()); // rob debug from vbu?
469   }
470
471   if (myFirstSurfType == AIS_KOS_Plane)
472     {
473       AIS::ComputeLengthBetweenPlanarFaces( TopoDS::Face(myFShape),
474                                             TopoDS::Face(mySShape),
475                                             myFirstPlane,
476                                             mySecondPlane,
477                                             myVal,
478                                             myFAttach,
479                                             mySAttach,
480                                             myDirAttach,
481                                             myAutomaticPosition,
482                                             myPosition );
483       if (myAutomaticPosition && myIsSetBndBox)
484         myPosition = AIS::TranslatePointToBound( myPosition, myDirAttach, myBndBox );
485
486       myDrawer->LengthAspect()->Arrow1Aspect()->SetLength( myArrowSize );
487       myDrawer->LengthAspect()->Arrow2Aspect()->SetLength( myArrowSize );
488
489       // Find text of the face
490
491       DsgPrs_LengthPresentation::Add( aPresentation,
492                                       myDrawer,
493                                       myText,
494                                       myFAttach,
495                                       mySAttach,
496                                       myFirstPlane,
497                                       myDirAttach,
498                                       myPosition,
499                                       mySymbolPrs );
500     }
501   else
502     {
503       AIS::ComputeLengthBetweenCurvilinearFaces( TopoDS::Face(myFShape),
504                                                  TopoDS::Face(mySShape),
505                                                  myFirstBasisSurf,
506                                                  mySecondBasisSurf,
507                                                  myAutomaticPosition,
508                                                  myVal,
509                                                  myPosition,
510                                                  myFAttach,
511                                                  mySAttach,
512                                                  myDirAttach );
513       if (myAutomaticPosition && myIsSetBndBox)
514         myPosition = AIS::TranslatePointToBound( myPosition, myDirAttach, myBndBox );
515
516       DsgPrs_LengthPresentation::Add( aPresentation,
517                                       myDrawer,
518                                       myText,
519                                       mySecondBasisSurf,
520                                       myFAttach,
521                                       mySAttach,
522                                       myDirAttach,
523                                       myPosition,
524                                       mySymbolPrs );
525     }
526 }
527
528
529 //=======================================================================
530 //function : ComputeEdgeFaceLength
531 //purpose  : Jean-Claude Vauthier 17/06/98
532 //           A quick implementation in order to edit the constraint of 
533 //           distance for a chamfer 3D.   
534 //=======================================================================
535
536 void AIS_LengthDimension::ComputeEdgeFaceLength (const Handle(Prs3d_Presentation )& aPresentation )
537 {
538
539   //The first attachment point is P1 from the reference Edge
540   //Find the second attachment point which belongs to the reference face
541   //Iterate over the edges of the face and find the point FP1...
542   //....it is the closest point according to P1
543
544   const TopoDS_Edge& E = TopoDS::Edge (mySShape); //The reference edge
545   const TopoDS_Face& F = TopoDS::Face (myFShape); //The reference face
546   TopoDS_Vertex V1, V2;
547   TopExp::Vertices (E, V1, V2);
548   myFAttach = BRep_Tool::Pnt (V1);
549   gp_Pnt P  = BRep_Tool::Pnt (V2);
550
551   TopExp_Explorer It (F, TopAbs_EDGE);
552   gp_Pnt2d FP1uv, FP2uv;
553   Standard_Real Dist1 = RealLast ();
554   Standard_Real Dist2 = RealLast ();
555   for (; It.More (); It.Next ()) {
556     const TopoDS_Edge FE = TopoDS::Edge(It.Current ());
557     TopExp::Vertices (FE, V1, V2);
558     gp_Pnt FP1c = BRep_Tool::Pnt (V1);
559     gp_Pnt FP2c = BRep_Tool::Pnt (V2);
560     Standard_Real Dc1 = myFAttach.SquareDistance (FP1c);
561     Standard_Real Dc2 = myFAttach.SquareDistance (FP2c);
562     if (Dc1 <= Dc2) {
563       if (Dc1 <= Dist1) {
564         Dc2 = P.SquareDistance (FP2c);
565         if (Dc2 <= Dist2) {
566           mySAttach  = FP1c;
567           Dist1 = Dc1;
568           Dist2 = Dc2;
569           BRep_Tool::UVPoints (FE, F, FP1uv, FP2uv); 
570         }
571       }
572     }
573     else {
574       if (Dc2 <= Dist1) {
575         Dc1 = P.SquareDistance (FP1c);
576         if (Dc1 <= Dist2) {
577           mySAttach = FP2c;
578           Dist1 = Dc2;
579           Dist2 = Dc1;
580           BRep_Tool::UVPoints (FE, F, FP2uv, FP1uv); 
581         }
582       }
583     }
584   }
585
586   gp_Vec OffsetDirection (0.0, 0.0, 0.0);
587
588   //The offset direction is the normal to the face at the point FP1 
589   BRepGProp_Face GF;
590   GF.Load (F);
591   GF.Normal (FP1uv.X(), FP1uv.Y(), P, OffsetDirection);
592
593   if (OffsetDirection.Magnitude () > Precision::Confusion ()) {
594     myDirAttach = gp_Dir (OffsetDirection);
595   }
596   else myDirAttach = gp::DZ ();
597
598
599   gp_Vec Vt (myDirAttach);
600   Vt.Multiply (1.5 * myVal); 
601   myPosition = mySAttach.Translated (Vt);
602
603   DsgPrs_LengthPresentation::Add(aPresentation,
604                                  myDrawer,
605                                  myText,        
606                                  myFAttach,
607                                  mySAttach,
608                                  myDirAttach,
609                                  myPosition,
610                                  mySymbolPrs);
611
612 }
613
614
615 //=======================================================================
616 //function : ComputeTwoEdgesLength
617 //purpose  : 
618 //=======================================================================
619
620 void AIS_LengthDimension::ComputeTwoEdgesLength( const Handle( Prs3d_Presentation )& aPresentation,
621                                                  const Handle( AIS_Drawer )& aDrawer,
622                                                  const TCollection_ExtendedString & aText,
623                                                  const Standard_Real ArrowSize,
624                                                  const TopoDS_Edge & FirstEdge,
625                                                  const TopoDS_Edge & SecondEdge,
626                                                  const Handle( Geom_Plane )& Plane,
627                                                  const Standard_Boolean AutomaticPos,
628                                                  const Standard_Boolean IsSetBndBox,
629                                                  const Bnd_Box & BndBox,
630                                                  Standard_Integer & ExtShape,
631                                                  Standard_Real & Val,
632                                                  gp_Dir & DirAttach,
633                                                  gp_Pnt & Position,
634                                                  gp_Pnt & FirstAttach,
635                                                  gp_Pnt & SecondAttach,
636                                                  DsgPrs_ArrowSide & SymbolPrs )
637 {
638   BRepAdaptor_Curve cu1( FirstEdge );
639   if (cu1.GetType() != GeomAbs_Line) return;
640   BRepAdaptor_Curve cu2( SecondEdge );
641   if (cu2.GetType() != GeomAbs_Line) return;
642   
643   // 3d lines
644   Handle(Geom_Curve) geom1,geom2;
645   gp_Pnt ptat11,ptat12,ptat21,ptat22;//,pint3d;
646   
647   Standard_Boolean isInfinite1(Standard_False),isInfinite2(Standard_False);
648   Standard_Integer ext(ExtShape);
649   Handle(Geom_Curve) extCurv;
650   if (!AIS::ComputeGeometry(FirstEdge,
651                             SecondEdge,
652                             ExtShape,
653                             geom1,
654                             geom2,
655                             ptat11,
656                             ptat12,
657                             ptat21,
658                             ptat22,
659                             extCurv,
660                             isInfinite1,
661                             isInfinite2,
662                             Plane)) 
663     {
664       return;
665     }
666   ExtShape = ext;
667   aPresentation->SetInfiniteState(isInfinite1 || isInfinite2);
668   const Handle(Geom_Line)& geom_lin1 = (Handle(Geom_Line)&) geom1;
669   const Handle(Geom_Line)& geom_lin2 = (Handle(Geom_Line)&) geom2;
670   const gp_Lin& l1 = geom_lin1->Lin();
671   const gp_Lin& l2 = geom_lin2->Lin();
672   
673   // New: computation of myVal
674   Val = l1.Distance( l2 );
675
676   DirAttach = l1.Direction();
677
678   // size
679   Standard_Real arrsize = ArrowSize;
680  
681   if (AutomaticPos) {
682     gp_Pnt curpos;
683     if ( !isInfinite1 ) {
684       gp_Pnt p2 = ElCLib::Value(ElCLib::Parameter(l2,ptat11),l2);
685       curpos.SetXYZ((ptat11.XYZ()+p2.XYZ())/2.);
686     }
687     else if (!isInfinite2) {
688       gp_Pnt p2 = ElCLib::Value(ElCLib::Parameter(l1,ptat21),l1);
689       curpos.SetXYZ((ptat21.XYZ()+p2.XYZ())/2.);
690     }
691     else {
692       curpos.SetXYZ((l1.Location().XYZ()+l2.Location().XYZ())/2.);
693     }
694     // offset to avoid confusion Edge and Dimension
695     gp_Vec offset(DirAttach);
696     offset = offset*ArrowSize*(-10.);
697     curpos.Translate(offset);
698     Position = curpos;
699   }
700   else {    // the point is projected in the plane
701     // it is patch!
702     Position = AIS::ProjectPointOnPlane( Position, Plane->Pln() );
703   }
704
705   // find attachment points 
706   if (!isInfinite1) {
707     if (Position.Distance(ptat11) > Position.Distance(ptat12)) FirstAttach = ptat12;
708     else FirstAttach = ptat11;
709   }
710   else {
711     FirstAttach = ElCLib::Value(ElCLib::Parameter(l1,Position),l1);
712   }
713   
714   if (!isInfinite2) {
715     if (Position.Distance(ptat21) > Position.Distance(ptat22)) SecondAttach = ptat22;
716     else SecondAttach = ptat21;
717   }
718   else {
719     SecondAttach = ElCLib::Value(ElCLib::Parameter(l2,Position),l2);
720   }
721   
722   Standard_Real confusion(Precision::Confusion());
723   if (arrsize < confusion) arrsize = Val/10.;
724   if (Abs(Val) <= confusion) {arrsize = 0.;}
725
726   Handle(Prs3d_LengthAspect) la = aDrawer->LengthAspect();
727   Handle(Prs3d_ArrowAspect) arr = la->Arrow1Aspect();  
728   arr->SetLength(arrsize);
729   arr = la->Arrow2Aspect();
730   arr->SetLength(arrsize);
731
732   if ( ExtShape == 1)
733     SymbolPrs = DsgPrs_AS_FIRSTPT_LASTAR;
734   else if ( ExtShape == 2)
735     SymbolPrs = DsgPrs_AS_FIRSTAR_LASTPT;
736
737   if (AutomaticPos && IsSetBndBox)
738     Position = AIS::TranslatePointToBound( Position, DirAttach, BndBox );
739   
740   DsgPrs_LengthPresentation::Add(aPresentation,
741                                  aDrawer,
742                                  aText,        
743                                  FirstAttach,
744                                  SecondAttach,
745                                  DirAttach,
746                                  Position,
747                                  SymbolPrs);
748
749   if ( (ExtShape != 0) &&  !extCurv.IsNull()) {
750     gp_Pnt pf, pl;
751     if ( ExtShape == 1 ) {
752       if (!isInfinite1) {
753         pf = ptat11; 
754         pl = ptat12;
755       }
756       AIS::ComputeProjEdgePresentation( aPresentation, aDrawer, FirstEdge, geom_lin1, pf, pl );
757     }
758     else {
759       if (!isInfinite2) {
760         pf = ptat21; 
761         pl = ptat22;
762       }
763       AIS::ComputeProjEdgePresentation( aPresentation, aDrawer, SecondEdge, geom_lin2, pf, pl );
764     }
765   }
766 }
767
768 //=======================================================================
769 //function : ComputeOneEdgeOneVertexLength
770 //purpose  : 
771 //=======================================================================
772
773 void AIS_LengthDimension::ComputeOneEdgeOneVertexLength( const Handle( Prs3d_Presentation )& aPresentation,
774                                                         const Handle( AIS_Drawer )& aDrawer,
775                                                         const TCollection_ExtendedString & aText,
776                                                         const Standard_Real ArrowSize,
777                                                         const TopoDS_Shape & FirstShape,
778                                                         const TopoDS_Shape & SecondShape,
779                                                         const Handle( Geom_Plane )& Plane,
780                                                         const Standard_Boolean AutomaticPos,
781                                                         const Standard_Boolean IsSetBndBox,
782                                                         const Bnd_Box & BndBox,
783                                                         Standard_Integer & ExtShape,
784                                                         Standard_Real & Val,
785                                                         gp_Dir & DirAttach,
786                                                         gp_Pnt & Position,
787                                                         gp_Pnt & FirstAttach,
788                                                         gp_Pnt & SecondAttach,
789                                                         DsgPrs_ArrowSide & SymbolPrs )
790 {
791   TopoDS_Vertex thevertex;
792   TopoDS_Edge theedge;
793   Standard_Integer numedge;
794   
795   if (FirstShape.ShapeType() == TopAbs_VERTEX) {
796     thevertex = TopoDS::Vertex(FirstShape);
797     theedge   = TopoDS::Edge(SecondShape);
798     numedge = 2;// edge = 2nd shape
799   }
800   else {
801     thevertex = TopoDS::Vertex(SecondShape);
802     theedge   = TopoDS::Edge(FirstShape);
803     numedge = 1;  // edge = 1st shape
804   }
805
806   gp_Pnt ptonedge1,ptonedge2;
807   Handle(Geom_Curve) aCurve;
808   Handle(Geom_Curve) extCurv;
809   Standard_Boolean isInfinite;
810   Standard_Boolean isOnPlanEdge, isOnPlanVertex;
811   if (!AIS::ComputeGeometry(theedge,aCurve,ptonedge1,ptonedge2,extCurv,isInfinite,isOnPlanEdge,Plane))
812     return;
813   aPresentation->SetInfiniteState(isInfinite);
814   AIS::ComputeGeometry(thevertex, FirstAttach, Plane, isOnPlanVertex);
815
816   // take into consideration that only the curve can be projected 
817   if (!isOnPlanEdge && !isOnPlanVertex)
818     return;
819
820   if (!isOnPlanEdge) {
821     if (numedge == 1) ExtShape = 1;
822     else ExtShape = 2;
823   }
824   else if (!isOnPlanVertex) {
825     if (numedge == 1) ExtShape = 2;
826     else ExtShape = 1;
827   }
828   
829
830   const Handle(Geom_Line)& geom_lin = (Handle(Geom_Line)&) aCurve;
831   const gp_Lin& l = geom_lin->Lin();
832
833   // New: computation of Val
834   Val = l.Distance( FirstAttach );
835
836   DirAttach = l.Direction();
837   // size
838   Standard_Real arrsize = ArrowSize;
839   if (Abs(Val) <= Precision::Confusion()) {arrsize = 0.;}
840
841   if (AutomaticPos) {
842     gp_Pnt p = ElCLib::Value(ElCLib::Parameter(l,FirstAttach),l);
843     gp_Pnt curpos((FirstAttach.XYZ()+p.XYZ())/2.);
844     // offset to avoid confusion Edge and Dimension
845     gp_Vec offset(DirAttach);
846     offset = offset*ArrowSize*(-10.);
847     curpos.Translate(offset);
848     Position = curpos;
849   }
850   else {    // the point is projected in the plane
851     // it is patch!
852     Position = AIS::ProjectPointOnPlane( Position, Plane->Pln() );
853
854     /*
855     Standard_Real u,v;
856     ElSLib::Parameters(Plane->Pln() , Position, u, v);
857     Position = ElSLib::Value(u,v,Plane->Pln());
858     */
859   }
860   
861   if (!isInfinite) {
862     if (Position.Distance(ptonedge1) > Position.Distance(ptonedge2)) SecondAttach = ptonedge2;
863     else SecondAttach = ptonedge1;
864   }
865   else {
866     SecondAttach = ElCLib::Value(ElCLib::Parameter(l,Position),l);
867   }
868   
869   Handle(Prs3d_LengthAspect) la = aDrawer->LengthAspect();
870   Handle(Prs3d_ArrowAspect) arr = la->Arrow1Aspect();  
871   arr->SetLength(arrsize);
872   arr = la->Arrow2Aspect();
873   arr->SetLength(arrsize);
874
875   if (AutomaticPos && IsSetBndBox)
876     Position = AIS::TranslatePointToBound( Position, DirAttach, BndBox );
877
878   DsgPrs_LengthPresentation::Add(aPresentation,
879                                  aDrawer,
880                                  aText,
881                                  FirstAttach,
882                                  SecondAttach,
883                                  DirAttach,
884                                  Position,
885                                  SymbolPrs);  
886
887   //Display the pieces connecting to the curve if it is not in the WP
888  if (ExtShape != 0) {
889    
890    if (!extCurv.IsNull()) { // this is the edge that is not in the WP
891      AIS::ComputeProjEdgePresentation(aPresentation,aDrawer,theedge,geom_lin,ptonedge1,ptonedge2);
892    }
893    else { //  this is the point that is not in the WP
894      AIS::ComputeProjVertexPresentation(aPresentation,aDrawer,thevertex,FirstAttach);
895    }
896  }
897 }
898
899 //=======================================================================
900 //function : ComputeTwoVerticesLength
901 //purpose  : 
902 //=======================================================================
903
904 void AIS_LengthDimension::ComputeTwoVerticesLength( const Handle( Prs3d_Presentation )& aPresentation,
905                                                    const Handle( AIS_Drawer )& aDrawer,
906                                                    const TCollection_ExtendedString& aText,
907                                                    const Standard_Real ArrowSize,
908                                                    const TopoDS_Vertex& FirstVertex,
909                                                    const TopoDS_Vertex& SecondVertex,
910                                                    const Handle( Geom_Plane )& Plane,
911                                                    const Standard_Boolean AutomaticPos,
912                                                    const Standard_Boolean IsSetBndBox,
913                                                    const Bnd_Box& BndBox,
914                                                    const AIS_TypeOfDist TypeDist,
915                                                    Standard_Integer& ExtShape,
916                                                    Standard_Real& Val,
917                                                    gp_Dir& DirAttach,
918                                                    gp_Pnt& Position,
919                                                    gp_Pnt& FirstAttach,
920                                                    gp_Pnt& SecondAttach,
921                                                    DsgPrs_ArrowSide& SymbolPrs )
922 {
923   Standard_Boolean isOnPlane1, isOnPlane2;
924
925   AIS::ComputeGeometry( FirstVertex, FirstAttach, Plane, isOnPlane1);
926   AIS::ComputeGeometry( SecondVertex, SecondAttach, Plane, isOnPlane2);
927
928   // New: computation of Val
929   Val = FirstAttach.Distance( SecondAttach );
930
931   if (ExtShape == 0) {
932     if (isOnPlane1 && isOnPlane2)
933       ExtShape = 0;
934     else if ( isOnPlane1 && !isOnPlane2)
935       ExtShape = 2;
936     else if (!isOnPlane1 && isOnPlane2)
937       ExtShape = 1;
938     else
939       return ;
940   }
941   Standard_Real confusion(Precision::Confusion());
942   Standard_Boolean samePoint(FirstAttach.IsEqual(SecondAttach,confusion));
943
944   if (TypeDist == AIS_TOD_Vertical) DirAttach =  Plane->Pln().XAxis().Direction();
945   else if (TypeDist == AIS_TOD_Horizontal) DirAttach =  Plane->Pln().YAxis().Direction();
946   else {
947     if (!samePoint) {
948       DirAttach = gce_MakeDir(FirstAttach,SecondAttach);
949       DirAttach.Rotate(Plane->Pln().Axis(),M_PI/2.);
950     }
951   }
952   
953   // size
954   //Standard_Real arrsize = ArrowSize;
955   //if (Abs(Val) <= confusion) arrsize =0.;
956
957   if (AutomaticPos) {
958    if (!samePoint) {
959      gp_Pnt curpos((FirstAttach.XYZ()+SecondAttach.XYZ())/2.);
960      // offset to avoid confusion Edge and Dimension
961      gp_Vec offset(DirAttach);
962      offset = offset*ArrowSize*(-10.);
963      curpos.Translate(offset);
964      Position = curpos;
965    }
966    else {     
967      Position = gp_Pnt(FirstAttach.XYZ()+gp_XYZ(1.,1.,1.));
968      // it is patch!
969      Position = AIS::ProjectPointOnPlane( Position, Plane->Pln() );
970      DirAttach = gce_MakeDir(FirstAttach,Position);
971    }
972   }
973   else {   
974     // it is patch!
975     Position = AIS::ProjectPointOnPlane( Position, Plane->Pln() );
976   }
977
978  
979   Handle(Prs3d_LengthAspect) la = aDrawer->LengthAspect();
980   Handle(Prs3d_ArrowAspect) arr = la->Arrow1Aspect();  
981   arr->SetLength(ArrowSize);
982   arr = la->Arrow2Aspect();
983   arr->SetLength(ArrowSize);
984
985   // Type of arrows
986   if ( ExtShape == 1) SymbolPrs = DsgPrs_AS_FIRSTPT_LASTAR;
987   else if (ExtShape == 2) SymbolPrs = DsgPrs_AS_FIRSTAR_LASTPT;
988
989   if (AutomaticPos && IsSetBndBox)
990     Position = AIS::TranslatePointToBound( Position, DirAttach, BndBox );
991
992   DsgPrs_LengthPresentation::Add(aPresentation,
993                                  aDrawer,
994                                  aText,
995                                  FirstAttach,
996                                  SecondAttach,
997                                  DirAttach,
998                                  Position,
999                                  SymbolPrs);
1000
1001   // Calculate the projection of the vertex
1002   if ( ExtShape == 1)
1003     AIS::ComputeProjVertexPresentation(aPresentation, aDrawer, FirstVertex, FirstAttach);
1004   else if ( ExtShape == 2)
1005     AIS::ComputeProjVertexPresentation(aPresentation, aDrawer, SecondVertex, SecondAttach);
1006 }
1007
1008 //=======================================================================
1009 //function : ComputeTwoFaceSelection
1010 //purpose  : 
1011 //=======================================================================
1012
1013 void AIS_LengthDimension::ComputeFaceSelection( const Handle( SelectMgr_Selection )& aSelection )
1014 {
1015   Handle( SelectMgr_EntityOwner ) own = new SelectMgr_EntityOwner( this, 7 );
1016   Handle( Select3D_SensitiveSegment ) seg;
1017   Handle( Geom_TrimmedCurve ) curve; 
1018   Handle( Select3D_SensitiveCurve ) SensCurve;
1019
1020   Standard_Real ArrowLength = myDrawer->AngleAspect()->ArrowAspect()->Length();
1021
1022   gp_Pnt EndOfArrow1, EndOfArrow2;
1023   gp_Dir DirOfArrow1;
1024
1025   if (myFirstSurfType == AIS_KOS_Plane)
1026     {
1027       DsgPrs::ComputePlanarFacesLengthPresentation( ArrowLength,
1028                                                     ArrowLength,
1029                                                     myFAttach,
1030                                                     mySAttach,
1031                                                     myDirAttach,
1032                                                     myPosition,
1033                                                     myFirstPlane,
1034                                                     EndOfArrow1,
1035                                                     EndOfArrow2,
1036                                                     DirOfArrow1 );
1037       //Add attach lines
1038       seg = new Select3D_SensitiveSegment( own, myFAttach, EndOfArrow1 );
1039       aSelection->Add( seg );
1040       
1041       seg = new Select3D_SensitiveSegment( own, mySAttach, EndOfArrow2 );
1042       aSelection->Add( seg );
1043     }
1044   else // curvilinear case
1045     {
1046       if(mySecondBasisSurf.IsNull())
1047         return;
1048       
1049       Handle( Geom_Curve ) VCurve, UCurve;
1050       Standard_Real FirstU, deltaU = 0.0e0, FirstV, deltaV = 0.0e0;
1051       
1052       EndOfArrow1 = myFAttach;
1053       DsgPrs::ComputeCurvilinearFacesLengthPresentation( ArrowLength,
1054                                                          ArrowLength,
1055                                                          mySecondBasisSurf,
1056                                                          myFAttach,
1057                                                          mySAttach,
1058                                                          myDirAttach,
1059                                                          EndOfArrow2,
1060                                                          DirOfArrow1,
1061                                                          VCurve,
1062                                                          UCurve,
1063                                                          FirstU, deltaU,
1064                                                          FirstV, deltaV );
1065       // Add attach curves
1066       if (Abs( deltaU ) > Precision::PConfusion())
1067         {
1068           if (deltaU > 0.0)
1069             curve = new Geom_TrimmedCurve( VCurve, FirstU, FirstU + deltaU );
1070           else
1071             curve = new Geom_TrimmedCurve( VCurve, FirstU + deltaU, FirstU );
1072           SensCurve = new Select3D_SensitiveCurve( own, curve );
1073           aSelection->Add( SensCurve );
1074         }
1075       if (Abs( deltaV ) > Precision::PConfusion())
1076         {
1077           if (deltaV > 0.0)
1078             curve = new Geom_TrimmedCurve( UCurve, FirstV, FirstV + deltaV );
1079           else
1080             curve = new Geom_TrimmedCurve( UCurve, FirstV + deltaV, FirstV );
1081           SensCurve = new Select3D_SensitiveCurve( own, curve );
1082           aSelection->Add( SensCurve );
1083         }
1084     }
1085
1086   // Add the length's line
1087   gp_Pnt FirstPoint, LastPoint; // ends of length's line
1088   gp_Vec ArrowVec( DirOfArrow1 );
1089   ArrowVec *= ArrowLength;
1090   if (myVal <= Precision::Confusion())
1091     {
1092       if (myPosition.SquareDistance( EndOfArrow1 ) > ArrowLength*ArrowLength)
1093         {
1094           FirstPoint = myPosition;
1095           LastPoint = EndOfArrow1.Translated( ArrowVec );
1096           if (myPosition.SquareDistance( LastPoint ) < myPosition.SquareDistance( EndOfArrow1 ))
1097             LastPoint = EndOfArrow1.Translated( -ArrowVec );
1098         }
1099       else
1100         {
1101           FirstPoint = EndOfArrow1.Translated( ArrowVec );
1102           LastPoint = EndOfArrow1.Translated( -ArrowVec );
1103         }
1104     }
1105   else
1106     {
1107       gp_Lin LengthLine( myPosition, DirOfArrow1 );
1108       Standard_Real Par1 = ElCLib::Parameter( LengthLine, EndOfArrow1 );
1109       Standard_Real Par2 = ElCLib::Parameter( LengthLine, EndOfArrow2 );
1110       if (Par1 > 0.0 && Par2 > 0.0 || Par1 < 0.0 && Par2 < 0.0)
1111         {
1112           FirstPoint = myPosition;
1113           LastPoint  = (Abs( Par1 ) > Abs( Par2 ))? EndOfArrow1 : EndOfArrow2;
1114           LastPoint.Translate( ((Abs( Par1 ) > Abs( Par2 ))? -ArrowVec : ArrowVec) );
1115         }
1116       else
1117         {
1118           FirstPoint = EndOfArrow1;
1119           LastPoint  = EndOfArrow2;
1120         }
1121     }
1122   seg = new Select3D_SensitiveSegment( own, FirstPoint, LastPoint );
1123   aSelection->Add( seg );
1124 }
1125
1126 //=======================================================================
1127 //function : ComputeEdgeVertexSelection
1128 //purpose  : 
1129 //=======================================================================
1130
1131 void AIS_LengthDimension::ComputeEdgeVertexSelection(const Handle(SelectMgr_Selection)& aSelection)
1132 {
1133   //  ********** NB ->
1134   // in the case of a constraint relatively to the border of a face 
1135   // only the shape of this contour is valid
1136
1137   // Create 2 owner for edition of constraints  
1138   Handle(AIS_DimensionOwner) own1 = new AIS_DimensionOwner(this,7);
1139   Handle(AIS_DimensionOwner) own2 = new AIS_DimensionOwner(this,7);  
1140
1141   if (myExtShape != 0) {
1142     if (myExtShape == 1) {
1143       own1->SetShape(mySShape);
1144       own2->SetShape(mySShape);
1145     }
1146     else {
1147       own1->SetShape(myFShape);
1148       own2->SetShape(myFShape);
1149     }
1150   }
1151   else {
1152     own1->SetShape(myFShape);
1153     own2->SetShape(mySShape);
1154   }
1155   
1156
1157   gp_Lin L1 (myFAttach,myDirAttach);
1158   gp_Lin L2 (mySAttach,myDirAttach);
1159   gp_Pnt Proj1 = ElCLib::Value(ElCLib::Parameter(L1,myPosition),L1);
1160   gp_Pnt Proj2 = ElCLib::Value(ElCLib::Parameter(L2,myPosition),L2);
1161   gp_Lin L3;
1162
1163   Standard_Real confusion(Precision::Confusion());  
1164
1165   if (!Proj1.IsEqual(Proj2,confusion)) L3 = gce_MakeLin(Proj1,Proj2);
1166   else { 
1167     // cas of zero dimension
1168     // own1 is chosen by default
1169     L3 = gce_MakeLin(Proj1,myDirAttach);
1170     Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6));
1171     Handle(Select3D_SensitiveBox) box = new Select3D_SensitiveBox(own1,myPosition.X(),myPosition.Y(),myPosition.Z(),
1172                                                                   myPosition.X()+size,
1173                                                                   myPosition.Y()+size,
1174                                                                   myPosition.Z()+size);
1175     aSelection->Add(box);
1176   }
1177
1178   Standard_Real parmin,parmax,parcur;
1179   parmin = ElCLib::Parameter(L3,Proj1);
1180   parmax = parmin;
1181   
1182   parcur = ElCLib::Parameter(L3,Proj2);
1183   parmin = Min(parmin,parcur);
1184   parmax = Max(parmax,parcur);
1185
1186   parcur = ElCLib::Parameter(L3,myPosition);
1187   parmin = Min(parmin,parcur);
1188   parmax = Max(parmax,parcur);
1189
1190   gp_Pnt PointMin = ElCLib::Value(parmin,L3);
1191   gp_Pnt PointMax = ElCLib::Value(parmax,L3);
1192
1193   Handle(Select3D_SensitiveSegment) seg;
1194
1195   if (myFAttach.IsEqual(mySAttach,confusion) && !myPosition.IsEqual(mySAttach,confusion)) { 
1196       seg = new Select3D_SensitiveSegment(own1,mySAttach,myPosition);
1197       aSelection->Add(seg);
1198   }
1199   if (!PointMin.IsEqual(PointMax,confusion)) {    
1200     gp_Pnt MiddlePoint( (PointMin.XYZ() + PointMax.XYZ())/2);
1201     seg = new Select3D_SensitiveSegment(own1,PointMin,MiddlePoint);
1202     aSelection->Add(seg);
1203     seg = new Select3D_SensitiveSegment(own2,MiddlePoint, PointMax);
1204     aSelection->Add(seg);
1205   }
1206
1207   if (!myFAttach.IsEqual(Proj1,confusion)) {
1208     seg = new Select3D_SensitiveSegment(own1,myFAttach,Proj1);
1209     aSelection->Add(seg);
1210   }
1211   if (!mySAttach.IsEqual(Proj2,confusion)) {
1212     seg = new Select3D_SensitiveSegment(own2,mySAttach,Proj2);
1213     aSelection->Add(seg);
1214   }
1215 }
1216
1217
1218
1219
1220 //=======================================================================
1221 //function : KindOfDimension
1222 //purpose  : 
1223 //=======================================================================
1224  AIS_KindOfDimension AIS_LengthDimension::KindOfDimension() const 
1225 {
1226   return AIS_KOD_LENGTH;
1227 }
1228
1229 //=======================================================================
1230 //function : IsMovable
1231 //purpose  : 
1232 //=======================================================================
1233  Standard_Boolean AIS_LengthDimension::IsMovable() const 
1234 {
1235   return Standard_True;
1236 }
1237
1238 //=======================================================================
1239 //function : SetFirstShape
1240 //purpose  : 
1241 //=======================================================================
1242 void AIS_LengthDimension::SetFirstShape( const TopoDS_Shape& aFShape )
1243 {
1244   myFShape = aFShape;
1245
1246   if (myFShape.ShapeType() == TopAbs_FACE)
1247     AIS::InitFaceLength( TopoDS::Face( myFShape ), myFirstPlane, myFirstBasisSurf, myFirstSurfType, myFirstOffset );
1248 }
1249
1250 //=======================================================================
1251 //function : SetSecondShape
1252 //purpose  : 
1253 //=======================================================================
1254 void AIS_LengthDimension::SetSecondShape( const TopoDS_Shape& aSShape )
1255 {
1256   mySShape = aSShape;
1257
1258   if (mySShape.ShapeType() == TopAbs_FACE)
1259     AIS::InitFaceLength( TopoDS::Face( mySShape ), mySecondPlane, mySecondBasisSurf, mySecondSurfType, mySecondOffset );
1260 }