Salome HOME
Merge branch 'hydro/imps_2017' into V8_3_BR
[modules/geom.git] / src / OBJECT / GEOM_Annotation.cxx
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //  GEOM OBJECT : interactive object for Geometry entities visualization
24 //  File   : GEOM_Annotation.hxx
25 //  Module : GEOM
26 //
27 #include <GEOM_Annotation.hxx>
28
29 // OCCT includes
30 #include <AIS_InteractiveContext.hxx>
31 #include <Font_FTFont.hxx>
32 #include <Graphic3d_ArrayOfPoints.hxx>
33 #include <Graphic3d_ArrayOfSegments.hxx>
34 #include <Graphic3d_Camera.hxx>
35 #include <Graphic3d_HorizontalTextAlignment.hxx>
36 #include <Graphic3d_VerticalTextAlignment.hxx>
37 #include <Graphic3d_Vec4.hxx>
38 #include <OpenGl_Context.hxx>
39 #include <OpenGl_GraphicDriver.hxx>
40 #include <OpenGl_Group.hxx>
41 #include <OpenGl_PrimitiveArray.hxx>
42 #include <OpenGl_Structure.hxx>
43 #include <OpenGl_Text.hxx>
44 #include <OpenGl_View.hxx>
45 #include <OpenGl_Workspace.hxx>
46 #include <Prs3d_PointAspect.hxx>
47 #include <Prs3d_Root.hxx>
48 #include <Prs3d_Text.hxx>
49 #include <Prs3d_IsoAspect.hxx>
50 #include <Select3D_SensitiveBox.hxx>
51 #include <SelectMgr_EntityOwner.hxx>
52 #include <V3d_Viewer.hxx>
53 #include <V3d_View.hxx>
54
55 IMPLEMENT_STANDARD_RTTIEXT( GEOM_Annotation, AIS_InteractiveObject )
56
57 // =======================================================================
58 // function : Constructor
59 // purpose  :
60 // =======================================================================
61 GEOM_Annotation::GEOM_Annotation() : AIS_InteractiveObject()
62 {
63   SetPosition( gp_Pnt( 0.0, 0.0, 0.0 ) );
64   SetIsScreenFixed( Standard_False );
65   SetAttachPoint( gp_Pnt( 0.0, 0.0, 0.0 ) );
66   SetDisplayMode( 0 );
67   SetZLayer( Graphic3d_ZLayerId_Default );
68   SetAutoHide( Standard_True );
69 #if OCC_VERSION_LARGE <= 0x07010001
70   SetHilightMode( HighlightAll );
71 #endif
72   SetMutable( Standard_True );
73   SetDepthCulling( Standard_True );
74
75   Handle(Prs3d_TextAspect) aTextAspect = new Prs3d_TextAspect();
76   aTextAspect->SetHeight( 20.0 );
77   aTextAspect->SetColor( Quantity_Color( 1.0, 1.0, 1.0, Quantity_TOC_RGB ) );
78   myDrawer->SetTextAspect( aTextAspect );
79
80   Handle(Prs3d_LineAspect) aLineAspect =
81     new Prs3d_LineAspect( Quantity_NOC_WHITE, Aspect_TOL_SOLID, 1.0 );
82   myDrawer->SetLineAspect( aLineAspect );
83
84   Handle(Prs3d_LineAspect) aHiddenLineAspect =
85     new Prs3d_LineAspect( Quantity_NOC_WHITE, Aspect_TOL_DOT, 1.0 );
86   myDrawer->SetHiddenLineAspect( aHiddenLineAspect );
87
88   Handle(Prs3d_PointAspect) aPointAspect =
89     new Prs3d_PointAspect( Aspect_TOM_POINT, Quantity_NOC_WHITE, 4.0 );
90   myDrawer->SetPointAspect( aPointAspect );
91 }
92
93 // =======================================================================
94 // function : SetText
95 // purpose  :
96 // =======================================================================
97 void GEOM_Annotation::SetText( const TCollection_ExtendedString& theText )
98 {
99   if (myText != theText)
100   {
101     SetToUpdate();
102   }
103
104   myText = theText;
105 }
106
107 // =======================================================================
108 // function : SetPosition
109 // purpose  :
110 // =======================================================================
111 void GEOM_Annotation::SetPosition( const gp_Pnt& thePosition )
112 {
113   SetPosition( thePosition, Standard_True );
114 }
115
116 // =======================================================================
117 // function : SetPosition
118 // purpose  :
119 // =======================================================================
120 void GEOM_Annotation::SetPosition( const gp_Pnt& thePosition, const Standard_Boolean theUpdateSelection )
121 {
122   myPosition = thePosition;
123
124   if ( !myIsScreenFixed )
125   {
126     Handle(Graphic3d_TransformPers) aPersistence =
127       new Graphic3d_TransformPers( Graphic3d_TMF_ZoomRotatePers, thePosition );
128
129     AIS_InteractiveObject::SetTransformPersistence( aPersistence );
130   }
131
132   SetToUpdate();
133
134   if( theUpdateSelection )
135   {
136     UpdateSelection();
137   }
138 }
139
140 // =======================================================================
141 // function : SetIsScreenFixed
142 // purpose  :
143 // =======================================================================
144 void GEOM_Annotation::SetIsScreenFixed( const Standard_Boolean theIsFixed )
145 {
146   myIsScreenFixed = theIsFixed;
147
148   Handle(Graphic3d_TransformPers) aPersistence;
149
150   if (!myIsScreenFixed)
151   {
152     aPersistence = new Graphic3d_TransformPers( Graphic3d_TMF_ZoomRotatePers, myPosition );
153   }
154   else
155   {
156     aPersistence = new Graphic3d_TransformPers( Graphic3d_TMF_2d, Aspect_TOTP_CENTER );
157   }
158
159   AIS_InteractiveObject::SetTransformPersistence( aPersistence );
160
161   SetZLayer( myIsScreenFixed ? Graphic3d_ZLayerId_Topmost : Graphic3d_ZLayerId_Default );
162
163   SetToUpdate();
164
165   UpdateSelection();
166 }
167
168 // =======================================================================
169 // function : Set2dPosition
170 // purpose  :
171 // =======================================================================
172 void GEOM_Annotation::Set2dPosition( const Handle(V3d_View)& theView )
173 {
174   if ( myIsScreenFixed )
175   {
176     return;
177   }
178
179   gp_Pnt aPosition2d = ConvertPosition2d( myPosition, myAttach, theView );
180
181   SetIsScreenFixed( Standard_True );
182
183   SetPosition( aPosition2d );
184 }
185
186 // =======================================================================
187 // function : Set3dPosition
188 // purpose  :
189 // =======================================================================
190 void GEOM_Annotation::Set3dPosition( const Handle(V3d_View)& theView )
191 {
192   if ( !myIsScreenFixed )
193   {
194     return;
195   }
196
197   gp_Pnt aPosition3d = ConvertPosition3d( myPosition, myAttach, theView );
198
199   SetIsScreenFixed( Standard_False );
200
201   SetPosition( aPosition3d );
202 }
203
204 // =======================================================================
205 // function : SetAttachPoint
206 // purpose  :
207 // =======================================================================
208 void GEOM_Annotation::SetAttachPoint( const gp_Pnt& thePoint )
209 {
210   myAttach = thePoint;
211 }
212
213 // =======================================================================
214 // function : SetHilightShape
215 // purpose  : Sets shape (annotated shape) that will be used for hilighting.
216 // =======================================================================
217 void GEOM_Annotation::SetHilightShape( const TopoDS_Shape& theShape )
218 {
219   if ( myShape.IsEqual( theShape ) )
220   {
221     return;
222   }
223
224   myShape = theShape;
225   SetToUpdate();
226   UpdateSelection();
227 }
228
229 // =======================================================================
230 // function : SetColor
231 // purpose  :
232 // =======================================================================
233 void GEOM_Annotation::SetColor( const Quantity_Color& theColor )
234 {
235   SetTextColor( theColor );
236   SetLineColor( theColor );
237 }
238
239 // =======================================================================
240 // function : SetTextColor
241 // purpose  :
242 // =======================================================================
243 void GEOM_Annotation::SetTextColor( const Quantity_Color& theColor )
244 {
245   myDrawer->TextAspect()->SetColor( theColor );
246
247   SetToUpdate();
248 }
249
250 // =======================================================================
251 // function : SetLineColor
252 // purpose  :
253 // =======================================================================
254 void GEOM_Annotation::SetLineColor( const Quantity_Color& theColor )
255 {
256   myDrawer->LineAspect()->SetColor( theColor );
257   myDrawer->HiddenLineAspect()->SetColor( theColor );
258   myDrawer->PointAspect()->SetColor( theColor );
259
260   SetToUpdate();
261 }
262
263 // =======================================================================
264 // function : SetLineWidth
265 // purpose  :
266 // =======================================================================
267 void GEOM_Annotation::SetLineWidth( const Standard_Real theLineWidth )
268 {
269   if ( GetLineWidth() != theLineWidth )
270   {
271     myDrawer->LineAspect()->SetWidth( theLineWidth );
272     myDrawer->HiddenLineAspect()->SetWidth( theLineWidth );
273
274     SetToUpdate();
275   }
276 }
277
278 // =======================================================================
279 // function : SetLineStyle
280 // purpose  :
281 // =======================================================================
282 void GEOM_Annotation::SetLineStyle( const Aspect_TypeOfLine theStyle )
283 {
284   if ( GetLineStyle() != theStyle )
285   {
286     myDrawer->LineAspect()->SetTypeOfLine( theStyle );
287
288     SetToUpdate();
289   }
290 }
291
292 // =======================================================================
293 // function : SetHiddenLineStyle
294 // purpose  :
295 // =======================================================================
296 void GEOM_Annotation::SetHiddenLineStyle( const Aspect_TypeOfLine theStyle )
297 {
298   if ( GetHiddenLineStyle() != theStyle )
299   {
300     myDrawer->HiddenLineAspect()->SetTypeOfLine( theStyle );
301
302     SetToUpdate();
303   }
304 }
305
306 // =======================================================================
307 // function : SetTextHeight
308 // purpose  :
309 // =======================================================================
310 void GEOM_Annotation::SetTextHeight( const Standard_Real theHeight )
311 {
312   if ( GetTextHeight() != theHeight )
313   {
314     myDrawer->TextAspect()->SetHeight( theHeight );
315
316     SetToUpdate();
317   }
318 }
319
320 // =======================================================================
321 // function : SetFontAspect
322 // purpose  :
323 // =======================================================================
324 void GEOM_Annotation::SetFontAspect( const Font_FontAspect theFontAspect )
325 {
326   if ( GetFontAspect() != theFontAspect )
327   {
328     myDrawer->TextAspect()->Aspect()->SetTextFontAspect( theFontAspect );
329
330     SetToUpdate();
331   }
332 }
333
334 // =======================================================================
335 // function : SetFont
336 // purpose  :
337 // =======================================================================
338 void GEOM_Annotation::SetFont( const TCollection_AsciiString& theFont )
339 {
340   if ( GetFont() != theFont )
341   {
342     myDrawer->TextAspect()->Aspect()->SetFont( theFont );
343
344     SetToUpdate();
345   }
346 }
347
348 // =======================================================================
349 // function : SetDepthCulling
350 // purpose  :
351 // =======================================================================
352 void GEOM_Annotation::SetDepthCulling( const Standard_Boolean theToEnable )
353 {
354   if ( GetDepthCulling() != theToEnable )
355   {
356     myIsDepthCulling = theToEnable;
357
358     SetToUpdate();
359   }
360 }
361
362 // =======================================================================
363 // function : SetDefaultZLayer
364 // purpose  :
365 // =======================================================================
366 void GEOM_Annotation::SetDefaultZLayer()
367 {
368   SetZLayer( myIsScreenFixed ? Graphic3d_ZLayerId_Topmost : Graphic3d_ZLayerId_Default );
369
370   SetToUpdate();
371 }
372
373 // =======================================================================
374 // function : GetDefaultPosition
375 // purpose  :
376 // =======================================================================
377 gp_Pnt GEOM_Annotation::GetDefaultPosition( const Standard_Boolean theIsScreenFixed,
378                                             const gp_Pnt& theAttachPnt,
379                                             const Standard_Real theOffset,
380                                             const Handle(V3d_View)& theView )
381 {
382   Standard_Integer aWinWidth = 0;
383   Standard_Integer aWinHeight = 0;
384   theView->Window()->Size( aWinWidth, aWinHeight );
385
386   gp_Pnt aPositionProj = theView->Camera()->Project( theAttachPnt );
387   aPositionProj.SetX( (aPositionProj.X() / 2.) * aWinWidth  + theOffset );
388   aPositionProj.SetY( (aPositionProj.Y() / 2.) * aWinHeight + theOffset );
389   aPositionProj.SetZ( 0.0 );
390
391   if ( theIsScreenFixed )
392   {
393     return aPositionProj;
394   }
395
396   gp_Pnt aAttachProj = theView->Camera()->Project ( theAttachPnt );
397   gp_Pnt aPosition3d = theView->Camera()->UnProject ( gp_Pnt ( aPositionProj.X() / aWinWidth * 2.,
398                                                                aPositionProj.Y() / aWinHeight * 2., 
399                                                                aAttachProj.Z() ));
400
401   return aPosition3d;
402 }
403
404 // =======================================================================
405 // function : ConvertPosition2d
406 // purpose  :
407 // =======================================================================
408 gp_Pnt GEOM_Annotation::ConvertPosition2d( const gp_Pnt& thePosition,
409                                            const gp_Pnt& /*theAttach*/,
410                                            const Handle(V3d_View)& theView )
411 {
412   Standard_Integer aWinWidth = 0;
413   Standard_Integer aWinHeight = 0;
414   theView->Window()->Size( aWinWidth, aWinHeight );
415
416   gp_Pnt aPositionProj = theView->Camera()->Project( thePosition );
417   aPositionProj.SetX( (aPositionProj.X() / 2.) * aWinWidth );
418   aPositionProj.SetY( (aPositionProj.Y() / 2.) * aWinHeight );
419   aPositionProj.SetZ( 0.0 );
420   return aPositionProj;
421 }
422
423 // =======================================================================
424 // function : ConvertPosition3d
425 // purpose  :
426 // =======================================================================
427 gp_Pnt GEOM_Annotation::ConvertPosition3d( const gp_Pnt& thePosition,
428                                            const gp_Pnt& theAttach,
429                                            const Handle(V3d_View)& theView )
430 {
431   Standard_Integer aWinWidth = 0;
432   Standard_Integer aWinHeight = 0;
433   theView->Window()->Size( aWinWidth, aWinHeight );
434
435   gp_Pnt aAttachProj = theView->Camera()->Project( theAttach );
436   gp_Pnt aPosition3d =  theView->Camera()->UnProject(
437     gp_Pnt ( thePosition.X() / aWinWidth * 2., thePosition.Y() / aWinHeight * 2., aAttachProj.Z() ) );
438
439   return aPosition3d;
440 }
441
442 // =======================================================================
443 // function : Compute
444 // purpose  :
445 // =======================================================================
446 void GEOM_Annotation::Compute( const Handle(PrsMgr_PresentationManager3d)& /*thePresentationManager*/,
447                                const Handle(Prs3d_Presentation)&           thePresentation,
448                                const Standard_Integer                      theMode )
449 {
450   thePresentation->Clear();
451
452   if (theMode < 0)
453   {
454     return;
455   }
456
457   Handle(OpenGl_Group) aGroup = Handle(OpenGl_Group)::DownCast( Prs3d_Root::NewGroup( thePresentation ) );
458   if (aGroup.IsNull())
459   {
460     return;
461   }
462
463   Handle(Prs3d_TextAspect) anAsp = myDrawer->TextAspect();
464   NCollection_String aUtfText( myText.ToExtString() );
465   OpenGl_Annotation* aAnnotationDraw =
466     new OpenGl_Annotation( this, static_cast<Standard_Integer>( anAsp->Height() ), aGroup->GlStruct()->GlDriver() );
467
468   aAnnotationDraw->SetDepthMode( 0 );
469   aGroup->SetGroupPrimitivesAspect( myDrawer->TextAspect()->Aspect() );
470   aGroup->SetGroupPrimitivesAspect( myDrawer->LineAspect()->Aspect() );
471   aGroup->SetGroupPrimitivesAspect( myDrawer->PointAspect()->Aspect() );
472   aGroup->AddElement( aAnnotationDraw );
473
474   if ( !myIsDepthCulling )
475   {
476     OpenGl_Annotation* aAnnotationDraw =
477       new OpenGl_Annotation( this, static_cast<Standard_Integer>( anAsp->Height() ), aGroup->GlStruct()->GlDriver() );
478
479     aAnnotationDraw->SetDepthMode( GL_GREATER );
480     aGroup->SetPrimitivesAspect( myDrawer->TextAspect()->Aspect() );
481     aGroup->SetPrimitivesAspect( myDrawer->HiddenLineAspect()->Aspect() );
482     aGroup->SetPrimitivesAspect( myDrawer->PointAspect()->Aspect() );
483     aGroup->AddElement( aAnnotationDraw );
484   }
485
486   Bnd_Box aBox = TextBoundingBox();
487   if ( myIsScreenFixed )
488   {
489     gp_Trsf aOffset2d;
490     aOffset2d.SetTranslation( gp_Vec( myPosition.X(), myPosition.Y(), 0.0 ) );
491     aBox = aBox.Transformed( aOffset2d );
492   }
493
494   const gp_Pnt aBoxMin = aBox.CornerMin();
495   const gp_Pnt aBoxMax = aBox.CornerMax();
496   aGroup->ChangeBoundingBox() = Graphic3d_BndBox4f (
497     Graphic3d_Vec4( static_cast<Standard_ShortReal>( aBoxMin.X() ),
498                     static_cast<Standard_ShortReal>( aBoxMin.Y() ),
499                     static_cast<Standard_ShortReal>( aBoxMin.Z() ), 1.0F ),
500     Graphic3d_Vec4( static_cast<Standard_ShortReal>( aBoxMax.X() ),
501                     static_cast<Standard_ShortReal>( aBoxMax.Y() ),
502                     static_cast<Standard_ShortReal>( aBoxMax.Z() ), 1.0F ) );
503 }
504
505 // =======================================================================
506 // function : ComputeSelection
507 // purpose  :
508 // =======================================================================
509 void GEOM_Annotation::ComputeSelection( const Handle(SelectMgr_Selection)& theSelection,
510                                         const Standard_Integer             theMode )
511 {
512   if (theMode != GlobalSelectionMode())
513   {
514     return;
515   }
516
517   theSelection->Clear();
518
519   Bnd_Box aBox = TextBoundingBox();
520   if ( myIsScreenFixed )
521   {
522     gp_Trsf aOffset2d;
523     aOffset2d.SetTranslation( gp_Vec( myPosition.X(), myPosition.Y(), 0.0 ) );
524     aBox = aBox.Transformed( aOffset2d );
525   }
526
527   const Handle(GEOM_AnnotationOwner) anEntityOwner = new GEOM_AnnotationOwner( myShape, this, 10 );
528   const Handle(GEOM_AnnotationSensEntity) aSensitive =
529     new GEOM_AnnotationSensEntity( anEntityOwner, aBox, myIsDepthCulling );
530
531   theSelection->Add( aSensitive );
532 }
533
534 // =======================================================================
535 // function : TextBoundingBox
536 // purpose  :
537 // =======================================================================
538 Bnd_Box GEOM_Annotation::TextBoundingBox() const
539 {
540   Handle(Prs3d_TextAspect) anAsp = myDrawer->TextAspect();
541   Font_FTFont aFont;
542   unsigned int aResolution = GetContext()->CurrentViewer()->DefaultRenderingParams().Resolution;
543   if ( aFont.Init( anAsp->Aspect()->Font().ToCString(),
544                    anAsp->Aspect()->GetTextFontAspect(),
545                   (unsigned int)anAsp->Height(),
546                   aResolution ) )
547   {
548     const NCollection_String aText( (Standard_Utf16Char* )myText.ToExtString() );
549     const Font_Rect aFontRect = aFont.BoundingBox( aText, Graphic3d_HTA_CENTER, Graphic3d_VTA_CENTER );
550     Bnd_Box aBox;
551     aBox.Add( gp_Pnt( aFontRect.Left, aFontRect.Bottom, 0.0 ) );
552     aBox.Add( gp_Pnt( aFontRect.Right, aFontRect.Top, 0.0 ) );
553     return aBox;
554   }
555
556   return Bnd_Box();
557 }
558
559 // =======================================================================
560 // function : BeginDrag
561 // purpose  :
562 // =======================================================================
563 void GEOM_Annotation::BeginDrag()
564 {
565   myStartPosition = myPosition;
566 }
567
568 // =======================================================================
569 // function : Drag
570 // purpose  :
571 // =======================================================================
572 void GEOM_Annotation::Drag( const Standard_Integer theDx,
573                             const Standard_Integer theDy,
574                             const Handle(V3d_View)& theView )
575 {
576   if (myIsScreenFixed)
577   {
578     SetPosition( myStartPosition.Translated( gp_Vec( theDx, theDy, 0.0 ) ), Standard_False );
579   }
580   else
581   {
582     Standard_Integer aWidth, aHeight;
583     theView->Window()->Size( aWidth, aHeight );
584     gp_Pnt aNormalized = theView->Camera()->Project( myStartPosition );
585     gp_Pnt aNormalizedDrag =
586       aNormalized.Translated( gp_Vec( static_cast<Standard_Real>(theDx) * 2.0 / aWidth,
587                                       static_cast<Standard_Real>(theDy) * 2.0 / aHeight,
588                                       0.0 ) );
589
590     SetPosition( theView->Camera()->UnProject( aNormalizedDrag ), Standard_False );
591   }
592 }
593
594 // =======================================================================
595 // function : EndDrag
596 // purpose  :
597 // =======================================================================
598 void GEOM_Annotation::EndDrag()
599 {
600   UpdateSelection();
601 }
602
603 // =======================================================================
604 // function : UndoDrag
605 // purpose  :
606 // =======================================================================
607 void GEOM_Annotation::UndoDrag()
608 {
609   SetPosition( myStartPosition, Standard_True );
610 }
611
612 // =======================================================================
613 // subclass : OpenGl_Annotation
614 // function : Constructor
615 // purpose  : 
616 // =======================================================================
617 GEOM_Annotation::OpenGl_Annotation::OpenGl_Annotation( GEOM_Annotation* theAnnotation,
618                                                        const Standard_Integer theTextHeight,
619                                                        const OpenGl_GraphicDriver* theDriver )
620 : OpenGl_Element(),
621   myAISObject( theAnnotation ),
622   myText( theAnnotation->myText.ToExtString() ),
623   myDepthMode( 0 ),
624   myTextLineY( 0.f ),
625   myTextDPI( 0 )
626 {
627   // graphical resources for drawing text and underline
628   myTextParams.Height = theTextHeight;
629   myTextParams.HAlign = Graphic3d_HTA_CENTER;
630   myTextParams.VAlign = Graphic3d_VTA_CENTER;
631   myTextDraw = new OpenGl_Text( myText.ToCString(), OpenGl_Vec3(), myTextParams );
632   myTextLineDraw = new OpenGl_PrimitiveArray( theDriver );
633
634   // graphical resources for drawing extension line and marker
635   Handle(Graphic3d_ArrayOfSegments)
636   aExtVertexArray = new Graphic3d_ArrayOfSegments( 2 );
637   aExtVertexArray->AddVertex( 0.0, 0.0, 0.0 );
638   aExtVertexArray->AddVertex( 0.0, 0.0, 1.0 );
639   myExtLineDraw = new OpenGl_PrimitiveArray( theDriver, Graphic3d_TOPA_SEGMENTS,
640     aExtVertexArray->Indices(), aExtVertexArray->Attributes(), aExtVertexArray->Bounds() );
641
642   Handle(Graphic3d_ArrayOfPoints)
643   aExtMakerArray = new Graphic3d_ArrayOfPoints( 1 );
644   aExtMakerArray->AddVertex( 0.0, 0.0, 1.0 );
645   myExtMarkerDraw = new OpenGl_PrimitiveArray( theDriver, Graphic3d_TOPA_POINTS,
646     aExtMakerArray->Indices(), aExtMakerArray->Attributes(), aExtMakerArray->Bounds() );
647 }
648
649 // =======================================================================
650 // subclass : OpenGl_Annotation
651 // function : Destructor
652 // purpose  : 
653 // =======================================================================
654 GEOM_Annotation::OpenGl_Annotation::~OpenGl_Annotation()
655 {
656   Release( NULL );
657 }
658
659 // =======================================================================
660 // subclass : OpenGl_Annotation
661 // function : Release
662 // purpose  : Releases GL resources with the given GL context.
663 // =======================================================================
664 void GEOM_Annotation::OpenGl_Annotation::Release( OpenGl_Context* theCtx )
665 {
666   if (myTextDraw)
667   {
668     myTextDraw->Release( theCtx );
669     myTextLineDraw->Release( theCtx );
670     myExtLineDraw->Release( theCtx );
671     myExtMarkerDraw->Release( theCtx );
672   }
673   myTextDraw      = NULL;
674   myTextLineDraw  = NULL;
675   myExtLineDraw   = NULL;
676   myExtMarkerDraw = NULL;
677 }
678
679 // =======================================================================
680 // subclass : OpenGl_Annotation
681 // function : Render
682 // purpose  : Renders the annotation graphical elements.
683 // =======================================================================
684 void GEOM_Annotation::OpenGl_Annotation::Render( const Handle(OpenGl_Workspace)& theWorkspace ) const
685 {
686   const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
687
688   // ---------------------------------------------------------------------
689   // initialize text's font and configure some properties when DPI changes
690   // ---------------------------------------------------------------------
691
692   const unsigned int aDPI = theWorkspace->View()->RenderingParams().Resolution;
693   if (myTextDPI != aDPI)
694   {
695     const OpenGl_AspectText* anAspect = theWorkspace->AspectText();
696
697     // getting string size will also initialize font library
698     myTextDraw->StringSize( aContext,
699       myText, *anAspect, myTextParams, aDPI,
700       myTextSize.x, myTextSize.a, myTextSize.d );
701
702     myTextDPI = aDPI;
703     myTextSize.y = myTextSize.a - myTextSize.d;
704     switch (myTextParams.HAlign)
705     {
706       case Graphic3d_HTA_LEFT:   myTextUnderline.x() = 0.f; break;
707       case Graphic3d_HTA_CENTER: myTextUnderline.x() = -myTextSize.x / 2.f; break;
708       case Graphic3d_HTA_RIGHT:  myTextUnderline.x() = -myTextSize.x; break;
709       default:
710         break;
711     }
712     switch (myTextParams.VAlign)
713     {
714       case Graphic3d_VTA_TOPFIRSTLINE:
715       case Graphic3d_VTA_TOP:    myTextUnderline.y() = -myTextSize.y; break;
716       case Graphic3d_VTA_CENTER: myTextUnderline.y() = -myTextSize.y / 2.f; break;
717       case Graphic3d_VTA_BOTTOM: myTextUnderline.y() = myTextSize.d; break;
718       default:
719         break;
720     }
721
722     Handle(Graphic3d_ArrayOfSegments)
723     aVertexArray = new Graphic3d_ArrayOfSegments( 2 );
724     aVertexArray->AddVertex( myTextUnderline.x(), myTextUnderline.y(), 0.0f );
725     aVertexArray->AddVertex( myTextUnderline.x() + myTextSize.x, myTextUnderline.y(), 0.0f );
726     myTextLineDraw->InitBuffers( aContext, Graphic3d_TOPA_SEGMENTS,
727       aVertexArray->Indices(), aVertexArray->Attributes(), aVertexArray->Bounds() );
728   }
729
730   // ---------------------------------------------
731   // perform view culling test by attachment point
732   // ---------------------------------------------
733
734   const OpenGl_Vec4 aAttach( static_cast<float>( myAISObject->myAttach.X() ),
735                              static_cast<float>( myAISObject->myAttach.Y() ),
736                              static_cast<float>( myAISObject->myAttach.Z() ), 1.F );
737
738   const Handle(Graphic3d_Camera) aCamera = theWorkspace->View()->Camera();
739   const OpenGl_Mat4& aCameraProjMat = aCamera->ProjectionMatrixF();
740   const OpenGl_Mat4& aCameraViewMat = aCamera->OrientationMatrixF();
741   const OpenGl_Vec4 aAttachView = aCameraViewMat * aAttach;
742   if (myAISObject->myIsAutoHide)
743   {
744     const OpenGl_Vec4 aAttachClip = aCameraProjMat * aAttachView;
745     if (Abs( aAttachClip.x() ) > aAttachClip.w()
746      || Abs( aAttachClip.y() ) > aAttachClip.w()
747      || Abs( aAttachClip.z() ) > aAttachClip.w())
748     {
749       return;
750     }
751   }
752 #if OCC_VERSION_LARGE > 0x07010001
753   const Handle(Graphic3d_PresentationAttributes) aHighlightStyle = theWorkspace->HighlightStyle();
754   if (!aHighlightStyle.IsNull() && myAISObject->myHilightMode == HighlightLabel)
755   {
756     Handle(Graphic3d_PresentationAttributes) empty;
757     theWorkspace->SetHighlightStyle(empty);
758     theWorkspace->ApplyAspectLine();
759   }
760 #else    
761   const bool toHighlight = theWorkspace->ToHighlight();
762
763   if (toHighlight && myAISObject->myHilightMode == HighlightLabel)
764   {
765     theWorkspace->SetHighlight( false );
766     theWorkspace->ApplyAspectLine();
767   }
768 #endif
769   
770   GLint myOldDepthMode = 0;
771
772   if ( myDepthMode )
773   {
774     aContext->core11fwd->glGetIntegerv( GL_DEPTH_FUNC, &myOldDepthMode );
775     aContext->core11fwd->glDepthFunc( myDepthMode );
776   }
777
778   // -------------------------------------------------------------
779   // render text label in current persistence matrix and underline
780   // -------------------------------------------------------------
781
782   if ( myAISObject->myIsScreenFixed )
783   {
784     // use text position property instead of matrix setup 
785     // to avoid jittering when dragging text
786     myTextDraw->SetPosition( OpenGl_Vec3( static_cast<float>( myAISObject->myPosition.X() ),
787                                           static_cast<float>( myAISObject->myPosition.Y() ),
788                                           static_cast<float>( myAISObject->myPosition.Z() ) ) );
789   }
790
791   myTextDraw->Render( theWorkspace );
792
793   // ------------------------------------------------------------
794   // render annotation text's underline
795   // ------------------------------------------------------------
796
797   if ( myAISObject->myIsScreenFixed )
798   {
799     // setup local transformation (in 2D persistence reference)
800     // to represent position of annotation label on screen
801     const OpenGl_Mat4& aViewMat = aContext->WorldViewState.Current();
802     OpenGl_Mat4 aPositionMat;
803     aPositionMat.SetValue( 0, 3, static_cast<float>( myAISObject->myPosition.X() ) );
804     aPositionMat.SetValue( 1, 3, static_cast<float>( myAISObject->myPosition.Y() ) );
805     aPositionMat.SetValue( 2, 3, static_cast<float>( myAISObject->myPosition.Z() ) );
806     OpenGl_Mat4 aPosViewMat = aViewMat * aPositionMat;
807     aContext->WorldViewState.Push();
808     aContext->WorldViewState.SetCurrent( aPosViewMat );
809     aContext->ApplyModelViewMatrix();
810   }
811
812   myTextLineDraw->Render( theWorkspace );
813
814   // ------------------------------------------------------------
815   // render dynamic extension line using synthetic transformation
816   // ------------------------------------------------------------
817
818   OpenGl_Vec4 aCenter (0.f, 0.f, 0.f, 1.f);
819   switch (myTextParams.HAlign)
820   {
821     case Graphic3d_HTA_LEFT:   aCenter.x() =  myTextSize.x / 2.f; break;
822     case Graphic3d_HTA_CENTER: aCenter.x() = 0.f; break;
823     case Graphic3d_HTA_RIGHT:  aCenter.x() = -myTextSize.x / 2.f; break;
824     default: break;
825   }
826   switch (myTextParams.VAlign)
827   {
828     case Graphic3d_VTA_TOPFIRSTLINE:
829     case Graphic3d_VTA_TOP:    aCenter.y() = -myTextSize.y / 2.f; break;
830     case Graphic3d_VTA_CENTER: aCenter.y() = 0.f; break;
831     case Graphic3d_VTA_BOTTOM: aCenter.y() =  myTextSize.y / 2.f; break;
832     default: break;
833   }
834
835   // compute label's center in view coordinate space
836   const OpenGl_Mat4& aViewMat = aContext->WorldViewState.Current();
837   const OpenGl_Vec4 aCenterView = aViewMat * aCenter;
838
839   // the value below defines whether the extension line should be hanging
840   // on the left side of the label or on the right
841   const bool isLeftHanded = aAttachView.x() < aCenterView.x();
842
843   // compute extension line point at the text label in view coordinate space
844   const OpenGl_Vec4 aHingeView = aViewMat * OpenGl_Vec4(
845     ( isLeftHanded ? myTextUnderline.x() : myTextUnderline.x() + myTextSize.x ), myTextUnderline.y(), 0.0f, 1.0f );
846
847   // prepare matrix to specify geometry of extension line in view space
848   // by multiplication of unit z coordinate vector on given matrix.
849   OpenGl_Mat4 aExtGeometryMat;
850   aExtGeometryMat.SetColumn( 2, aAttachView - aHingeView );
851   aExtGeometryMat.SetColumn( 3, aHingeView );
852
853   // setup and draw
854   aContext->ModelWorldState.Push();
855   aContext->ModelWorldState.SetIdentity();
856   aContext->WorldViewState.Push();
857   aContext->WorldViewState.SetCurrent( aExtGeometryMat );
858   aContext->ApplyModelViewMatrix();
859
860   myExtLineDraw->Render( theWorkspace );
861   myExtMarkerDraw->Render( theWorkspace );
862
863   // ------------------------------------------------------------
864   // restore original state
865   // ------------------------------------------------------------
866
867   aContext->ModelWorldState.Pop();
868   aContext->WorldViewState.Pop();
869
870   if ( myOldDepthMode )
871   {
872     aContext->core11fwd->glDepthFunc( myOldDepthMode );
873   }
874
875   if ( myAISObject->myIsScreenFixed )
876   {
877     aContext->WorldViewState.Pop();
878   }
879
880   aContext->ApplyModelViewMatrix();
881   
882 #if OCC_VERSION_LARGE > 0x07010001
883   theWorkspace->SetHighlightStyle(aHighlightStyle);
884 #else
885   if ( toHighlight != theWorkspace->ToHighlight() )
886   {
887     theWorkspace->SetHighlight( toHighlight );
888   }
889 #endif
890 }
891
892 // =======================================================================
893 // subclass : GEOM_AnnotationOwner
894 // function : HilightWithColor
895 // purpose  : Perform highlighting of the presentation.
896 // =======================================================================
897 void GEOM_Annotation::GEOM_AnnotationOwner::HilightWithColor( const Handle(PrsMgr_PresentationManager3d)& thePM,
898 #if OCC_VERSION_LARGE > 0x07010001
899                                                               const Handle(Prs3d_Drawer)& theStyle,
900 #else                   
901                                                               const Handle(Graphic3d_HighlightStyle)& theStyle,
902 #endif                  
903                                                               const Standard_Integer theMode )
904 {
905   if ( myPrsSh.IsNull() )
906   {
907     Handle(Prs3d_Drawer) aDrawer = new Prs3d_Drawer;
908 #if OCC_VERSION_LARGE > 0x07010001
909     aDrawer->Link( theStyle );
910 #else
911     aDrawer->Link( Selectable()->HilightAttributes() );
912 #endif
913     Handle(Prs3d_IsoAspect) aUIsoAspect = new Prs3d_IsoAspect(
914       aDrawer->UIsoAspect()->Aspect()->Color(),
915       aDrawer->UIsoAspect()->Aspect()->Type(),
916       aDrawer->UIsoAspect()->Aspect()->Width(), 0 );
917
918     Handle(Prs3d_IsoAspect) aVIsoAspect = new Prs3d_IsoAspect(
919       aDrawer->UIsoAspect()->Aspect()->Color(),
920       aDrawer->UIsoAspect()->Aspect()->Type(),
921       aDrawer->UIsoAspect()->Aspect()->Width(), 0 );
922
923     aDrawer->SetIsoOnPlane( Standard_False );
924     aDrawer->SetUIsoAspect( aUIsoAspect );
925     aDrawer->SetVIsoAspect( aVIsoAspect );
926     myPrsSh = new StdSelect_Shape( myShape, aDrawer );
927   }
928
929   myPrsSh->SetZLayer ( Selectable()->ZLayer() );
930   
931   thePM->Color( Selectable(), theStyle, theMode, NULL, Graphic3d_ZLayerId_Topmost );
932
933   thePM->Color( myPrsSh, theStyle, theMode, Selectable(), Graphic3d_ZLayerId_Topmost );
934 }
935
936 // =======================================================================
937 // subclass : GEOM_AnnotationOwner
938 // function : Unhilight
939 // purpose  : Removes highlighting from the type of shape.
940 // =======================================================================
941 void GEOM_Annotation::GEOM_AnnotationOwner::Unhilight ( const Handle(PrsMgr_PresentationManager)& thePM,
942                                                         const Standard_Integer theMode )
943 {
944   SelectMgr_EntityOwner::Unhilight( thePM, theMode );
945   
946 #if OCC_VERSION_LARGE > 0x07010001
947   thePM->Unhighlight( myPrsSh );
948 #else
949   thePM->Unhighlight( myPrsSh, theMode );
950 #endif
951 }
952
953 // =======================================================================
954 // subclass : GEOM_AnnotationOwner
955 // function : Clear
956 // purpose  : Clears the presentation manager object aPM of all shapes
957 // with the given selection mode.
958 // =======================================================================
959 void GEOM_Annotation::GEOM_AnnotationOwner::Clear ( const Handle(PrsMgr_PresentationManager)& thePM,
960                                                     const Standard_Integer theMode )
961 {
962   SelectMgr_EntityOwner::Clear( thePM, theMode );
963
964   if ( !myPrsSh.IsNull() ) {
965     thePM->Clear( myPrsSh, theMode );
966   }
967
968   myPrsSh.Nullify();
969 }