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