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