0024245: TKOpenGL - use Message_Messenger interface to report issues
[occt.git] / src / OpenGl / OpenGl_Structure.cxx
CommitLineData
b311480e 1// Created on: 2011-08-01
2// Created by: Sergey ZERCHANINOV
3// Copyright (c) 2011-2012 OPEN CASCADE SAS
4//
5// The content of this file is subject to the Open CASCADE Technology Public
6// License Version 6.5 (the "License"). You may not use the content of this file
7// except in compliance with the License. Please obtain a copy of the License
8// at http://www.opencascade.org and read it completely before using this file.
9//
10// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12//
13// The Original Code and all software distributed under the License is
14// distributed on an "AS IS" basis, without warranty of any kind, and the
15// Initial Developer hereby disclaims all such warranties, including without
16// limitation, any warranties of merchantability, fitness for a particular
17// purpose or non-infringement. Please see the License for the specific terms
18// and conditions governing the rights and limitations under the License.
19
5f8b738e 20#include <OpenGl_GlCore11.hxx>
21
2166f0fa
SK
22#include <OpenGl_Structure.hxx>
23
2166f0fa 24#include <OpenGl_Workspace.hxx>
27eed937 25#include <OpenGl_Vec.hxx>
2166f0fa 26#include <OpenGl_View.hxx>
4269bd1b 27#include <OpenGl_CappingAlgo.hxx>
28#include <OpenGl_Context.hxx>
2166f0fa
SK
29#include <OpenGl_telem_util.hxx>
30
27eed937 31//! Auxiliary class for bounding box presentation
32class OpenGl_BndBoxPrs : public OpenGl_Element
33{
34
35public:
36
37 //! Main constructor
38 OpenGl_BndBoxPrs (const CALL_DEF_BOUNDBOX& theBndBox)
39 {
40 const float Xm = theBndBox.Pmin.x;
41 const float Ym = theBndBox.Pmin.y;
42 const float Zm = theBndBox.Pmin.z;
43 const float XM = theBndBox.Pmax.x;
44 const float YM = theBndBox.Pmax.y;
45 const float ZM = theBndBox.Pmax.z;
46 myVerts[0] = OpenGl_Vec3 (Xm, Ym, Zm);
47 myVerts[1] = OpenGl_Vec3 (Xm, Ym, ZM);
48 myVerts[2] = OpenGl_Vec3 (Xm, YM, ZM);
49 myVerts[3] = OpenGl_Vec3 (Xm, YM, Zm);
50 myVerts[4] = OpenGl_Vec3 (Xm, Ym, Zm);
51 myVerts[5] = OpenGl_Vec3 (XM, Ym, Zm);
52 myVerts[6] = OpenGl_Vec3 (XM, Ym, ZM);
53 myVerts[7] = OpenGl_Vec3 (XM, YM, ZM);
54 myVerts[8] = OpenGl_Vec3 (XM, YM, Zm);
55 myVerts[9] = OpenGl_Vec3 (XM, Ym, Zm);
56 myVerts[10] = OpenGl_Vec3 (XM, YM, Zm);
57 myVerts[11] = OpenGl_Vec3 (Xm, YM, Zm);
58 myVerts[12] = OpenGl_Vec3 (Xm, YM, ZM);
59 myVerts[13] = OpenGl_Vec3 (XM, YM, ZM);
60 myVerts[14] = OpenGl_Vec3 (XM, Ym, ZM);
61 myVerts[15] = OpenGl_Vec3 (Xm, Ym, ZM);
62 }
63
64 //! Render presentation
65 virtual void Render (const Handle(OpenGl_Workspace)& theWorkspace) const
66 {
67 // Apply line aspect
68 const OpenGl_AspectLine* anAspectLine = theWorkspace->AspectLine (Standard_True);
69 const Handle(OpenGl_Texture) aPrevTexture = theWorkspace->DisableTexture();
70
71 glDisable (GL_LIGHTING);
72 if ((theWorkspace->NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE)) != 0)
73 {
74 glDepthMask (GL_FALSE);
75 }
76
77 // Use highlight colors
78 glColor3fv ((theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT) ? theWorkspace->HighlightColor->rgb : anAspectLine->Color().rgb);
79
80 glEnableClientState (GL_VERTEX_ARRAY);
81 glVertexPointer (3, GL_FLOAT, 0, (GLfloat* )&myVerts);
82 glDrawArrays (GL_LINE_STRIP, 0, 16);
83 glDisableClientState (GL_VERTEX_ARRAY);
84
85 // restore aspects
86 if (!aPrevTexture.IsNull())
87 {
88 theWorkspace->EnableTexture (aPrevTexture);
89 }
90 }
91
92 //! Release graphical resources
93 virtual void Release (const Handle(OpenGl_Context)& )
94 {
95 //
96 }
97
98protected:
99
100 //! Protected destructor
101 virtual ~OpenGl_BndBoxPrs() {}
102
103private:
104
105 OpenGl_Vec3 myVerts[16]; //!< vertices array
106
107public:
108
109 DEFINE_STANDARD_ALLOC
110
111};
2166f0fa
SK
112
113/*----------------------------------------------------------------------*/
114
4269bd1b 115// =======================================================================
116// function : call_util_transpose_mat
117// purpose :
118// =======================================================================
2166f0fa
SK
119static void call_util_transpose_mat (float tmat[16], float mat[4][4])
120{
121 int i, j;
122
123 for (i=0; i<4; i++)
124 for (j=0; j<4; j++)
125 tmat[j*4+i] = mat[i][j];
126}
127
4269bd1b 128// =======================================================================
129// function : OpenGl_Structure
130// purpose :
131// =======================================================================
2166f0fa
SK
132OpenGl_Structure::OpenGl_Structure ()
133: myTransformation(NULL),
134 myTransPers(NULL),
2166f0fa
SK
135 myAspectLine(NULL),
136 myAspectFace(NULL),
137 myAspectMarker(NULL),
138 myAspectText(NULL),
139 myHighlightBox(NULL),
140 myHighlightColor(NULL),
59f45b7c 141 myNamedStatus(0),
142 myZLayer(0)
2166f0fa
SK
143{
144}
145
4269bd1b 146// =======================================================================
147// function : ~OpenGl_Structure
148// purpose :
149// =======================================================================
5e27df78 150OpenGl_Structure::~OpenGl_Structure()
2166f0fa 151{
5e27df78 152 Release (Handle(OpenGl_Context)());
153 delete myTransformation; myTransformation = NULL;
154 delete myTransPers; myTransPers = NULL;
2166f0fa
SK
155}
156
4269bd1b 157// =======================================================================
158// function : SetTransformation
159// purpose :
160// =======================================================================
2166f0fa
SK
161void OpenGl_Structure::SetTransformation(const float *AMatrix)
162{
163 if (!myTransformation)
5e27df78 164 myTransformation = new OpenGl_Matrix();
2166f0fa
SK
165
166 matcpy( myTransformation->mat, AMatrix );
167}
168
4269bd1b 169// =======================================================================
170// function : SetTransformPersistence
171// purpose :
172// =======================================================================
2166f0fa
SK
173void OpenGl_Structure::SetTransformPersistence(const CALL_DEF_TRANSFORM_PERSISTENCE &ATransPers)
174{
175 if (!myTransPers)
176 myTransPers = new TEL_TRANSFORM_PERSISTENCE;
177
178 myTransPers->mode = ATransPers.Flag;
179 myTransPers->pointX = ATransPers.Point.x;
180 myTransPers->pointY = ATransPers.Point.y;
181 myTransPers->pointZ = ATransPers.Point.z;
182}
183
4269bd1b 184// =======================================================================
185// function : SetAspectLine
186// purpose :
187// =======================================================================
2166f0fa
SK
188void OpenGl_Structure::SetAspectLine (const CALL_DEF_CONTEXTLINE &AContext)
189{
190 if (!myAspectLine)
5e27df78 191 myAspectLine = new OpenGl_AspectLine();
2166f0fa
SK
192 myAspectLine->SetContext( AContext );
193}
194
4269bd1b 195// =======================================================================
196// function : SetAspectFace
197// purpose :
198// =======================================================================
bf75be98 199void OpenGl_Structure::SetAspectFace (const Handle(OpenGl_Context)& theCtx,
200 const CALL_DEF_CONTEXTFILLAREA& theAspect)
2166f0fa
SK
201{
202 if (!myAspectFace)
bf75be98 203 {
5e27df78 204 myAspectFace = new OpenGl_AspectFace();
bf75be98 205 }
206 myAspectFace->Init (theCtx, theAspect);
2166f0fa
SK
207}
208
4269bd1b 209// =======================================================================
210// function : SetAspectMarker
211// purpose :
212// =======================================================================
a577aaab 213void OpenGl_Structure::SetAspectMarker (const Handle(OpenGl_Context)& theCtx,
214 const CALL_DEF_CONTEXTMARKER& theAspect)
2166f0fa
SK
215{
216 if (!myAspectMarker)
a577aaab 217 {
5e27df78 218 myAspectMarker = new OpenGl_AspectMarker();
a577aaab 219 }
220 myAspectMarker->Init (theCtx, theAspect);
2166f0fa
SK
221}
222
4269bd1b 223// =======================================================================
224// function : SetAspectText
225// purpose :
226// =======================================================================
2166f0fa
SK
227void OpenGl_Structure::SetAspectText (const CALL_DEF_CONTEXTTEXT &AContext)
228{
229 if (!myAspectText)
5e27df78 230 myAspectText = new OpenGl_AspectText();
2166f0fa
SK
231 myAspectText->SetContext( AContext );
232}
233
4269bd1b 234// =======================================================================
235// function : SetHighlightBox
236// purpose :
237// =======================================================================
5e27df78 238void OpenGl_Structure::SetHighlightBox (const Handle(OpenGl_Context)& theGlCtx,
239 const CALL_DEF_BOUNDBOX& theBoundBox)
2166f0fa 240{
5e27df78 241 if (myHighlightBox != NULL)
242 {
243 myHighlightBox->Release (theGlCtx);
244 }
2166f0fa 245 else
5e27df78 246 {
247 myHighlightBox = new OpenGl_Group();
248 }
2166f0fa 249
5e27df78 250 CALL_DEF_CONTEXTLINE aContextLine;
251 aContextLine.Color = theBoundBox.Color;
252 aContextLine.LineType = Aspect_TOL_SOLID;
253 aContextLine.Width = 1.0f;
254 myHighlightBox->SetAspectLine (aContextLine);
2166f0fa 255
27eed937 256 OpenGl_BndBoxPrs* aBndBoxPrs = new OpenGl_BndBoxPrs (theBoundBox);
257 myHighlightBox->AddElement (TelParray, aBndBoxPrs);
2166f0fa
SK
258}
259
4269bd1b 260// =======================================================================
261// function : ClearHighlightBox
262// purpose :
263// =======================================================================
5e27df78 264void OpenGl_Structure::ClearHighlightBox (const Handle(OpenGl_Context)& theGlCtx)
2166f0fa 265{
5e27df78 266 if (myHighlightBox != NULL)
2166f0fa 267 {
5e27df78 268 OpenGl_Element::Destroy (theGlCtx, myHighlightBox);
2166f0fa
SK
269 }
270}
271
4269bd1b 272// =======================================================================
273// function : SetHighlightColor
274// purpose :
275// =======================================================================
5e27df78 276void OpenGl_Structure::SetHighlightColor (const Handle(OpenGl_Context)& theGlCtx,
277 const Standard_ShortReal R,
278 const Standard_ShortReal G,
279 const Standard_ShortReal B)
2166f0fa 280{
5e27df78 281 ClearHighlightBox (theGlCtx);
282 if (myHighlightColor == NULL)
283 {
284 myHighlightColor = new TEL_COLOUR();
285 }
2166f0fa
SK
286
287 myHighlightColor->rgb[0] = R;
288 myHighlightColor->rgb[1] = G;
289 myHighlightColor->rgb[2] = B;
290 myHighlightColor->rgb[3] = 1.F;
291}
292
4269bd1b 293// =======================================================================
294// function : ClearHighlightColor
295// purpose :
296// =======================================================================
5e27df78 297void OpenGl_Structure::ClearHighlightColor (const Handle(OpenGl_Context)& theGlCtx)
2166f0fa 298{
5e27df78 299 ClearHighlightBox(theGlCtx);
300 delete myHighlightColor;
301 myHighlightColor = NULL;
2166f0fa
SK
302}
303
4269bd1b 304// =======================================================================
305// function : Connect
306// purpose :
307// =======================================================================
2166f0fa
SK
308void OpenGl_Structure::Connect (const OpenGl_Structure *AStructure)
309{
310 Disconnect (AStructure);
311 myConnected.Append(AStructure);
312}
313
4269bd1b 314// =======================================================================
315// function : Disconnect
316// purpose :
317// =======================================================================
2166f0fa
SK
318void OpenGl_Structure::Disconnect (const OpenGl_Structure *AStructure)
319{
320 OpenGl_ListOfStructure::Iterator its(myConnected);
321 while (its.More())
322 {
323 // Check for the given structure
324 if (its.Value() == AStructure)
325 {
326 myConnected.Remove(its);
327 return;
328 }
329 its.Next();
330 }
331}
332
4269bd1b 333// =======================================================================
334// function : AddGroup
335// purpose :
336// =======================================================================
2166f0fa
SK
337OpenGl_Group * OpenGl_Structure::AddGroup ()
338{
339 // Create new group
340 OpenGl_Group *g = new OpenGl_Group;
341 myGroups.Append(g);
342 return g;
343}
344
4269bd1b 345// =======================================================================
346// function : RemoveGroup
347// purpose :
348// =======================================================================
5e27df78 349void OpenGl_Structure::RemoveGroup (const Handle(OpenGl_Context)& theGlCtx,
350 const OpenGl_Group* theGroup)
2166f0fa 351{
5e27df78 352 for (OpenGl_ListOfGroup::Iterator anIter (myGroups); anIter.More(); anIter.Next())
2166f0fa
SK
353 {
354 // Check for the given group
5e27df78 355 if (anIter.Value() == theGroup)
2166f0fa
SK
356 {
357 // Delete object
5e27df78 358 OpenGl_Element::Destroy (theGlCtx, const_cast<OpenGl_Group*& > (anIter.ChangeValue()));
359 myGroups.Remove (anIter);
2166f0fa
SK
360 return;
361 }
2166f0fa
SK
362 }
363}
364
4269bd1b 365// =======================================================================
366// function : Clear
367// purpose :
368// =======================================================================
5e27df78 369void OpenGl_Structure::Clear (const Handle(OpenGl_Context)& theGlCtx)
2166f0fa 370{
5e27df78 371 // Release groups
372 for (OpenGl_ListOfGroup::Iterator anIter (myGroups); anIter.More(); anIter.Next())
2166f0fa
SK
373 {
374 // Delete objects
5e27df78 375 OpenGl_Element::Destroy (theGlCtx, const_cast<OpenGl_Group*& > (anIter.ChangeValue()));
2166f0fa
SK
376 }
377 myGroups.Clear();
378}
379
4269bd1b 380// =======================================================================
381// function : Render
382// purpose :
383// =======================================================================
2166f0fa
SK
384void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
385{
386 // Process the structure only if visible
387 if ( myNamedStatus & OPENGL_NS_HIDE )
388 return;
389
390 // Render named status
391 const Standard_Integer named_status = AWorkspace->NamedStatus;
392 AWorkspace->NamedStatus |= myNamedStatus;
393
394 // Is rendering in ADD or IMMEDIATE mode?
395 const Standard_Boolean isImmediate = (AWorkspace->NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE)) != 0;
396
397 // Apply local transformation
398 GLint matrix_mode = 0;
399 const OpenGl_Matrix *local_trsf = NULL;
400 if (myTransformation)
401 {
402 if (isImmediate)
403 {
404 float mat16[16];
405 call_util_transpose_mat (mat16, myTransformation->mat);
406 glGetIntegerv (GL_MATRIX_MODE, &matrix_mode);
407 glMatrixMode (GL_MODELVIEW);
408 glPushMatrix ();
409 glScalef (1.F, 1.F, 1.F);
410 glMultMatrixf (mat16);
411 }
412 else
413 {
414 glMatrixMode (GL_MODELVIEW);
415 glPushMatrix();
416
417 local_trsf = AWorkspace->SetStructureMatrix(myTransformation);
418 }
419 }
420
421 // Apply transform persistence
422 const TEL_TRANSFORM_PERSISTENCE *trans_pers = NULL;
423 if ( myTransPers && myTransPers->mode != 0 )
424 {
425 trans_pers = AWorkspace->ActiveView()->BeginTransformPersistence( myTransPers );
426 }
427
2166f0fa
SK
428 // Apply aspects
429 const OpenGl_AspectLine *aspect_line = AWorkspace->AspectLine(Standard_False);
430 const OpenGl_AspectFace *aspect_face = AWorkspace->AspectFace(Standard_False);
431 const OpenGl_AspectMarker *aspect_marker = AWorkspace->AspectMarker(Standard_False);
432 const OpenGl_AspectText *aspect_text = AWorkspace->AspectText(Standard_False);
433 if (myAspectLine)
434 AWorkspace->SetAspectLine(myAspectLine);
435 if (myAspectFace)
436 AWorkspace->SetAspectFace(myAspectFace);
437 if (myAspectMarker)
438 AWorkspace->SetAspectMarker(myAspectMarker);
439 if (myAspectText)
440 AWorkspace->SetAspectText(myAspectText);
441
442 // Apply highlight box
443 if (myHighlightBox)
444 myHighlightBox->Render( AWorkspace );
445
446 // Apply highlight color
447 const TEL_COLOUR *highlight_color = AWorkspace->HighlightColor;
448 if (myHighlightColor)
449 AWorkspace->HighlightColor = myHighlightColor;
450
451 // Render connected structures
452 OpenGl_ListOfStructure::Iterator its(myConnected);
453 while (its.More())
454 {
455 its.Value()->Render(AWorkspace);
456 its.Next();
457 }
458
4269bd1b 459 // Set up plane equations for non-structure transformed global model-view matrix
460 const Handle(OpenGl_Context)& aContext = AWorkspace->GetGlContext();
461
462 // Collect planes which should be turned on for structure
463 Graphic3d_SetOfHClipPlane aPlanesOn;
464 Graphic3d_SetOfHClipPlane::Iterator aPlaneIt (myClipPlanes);
465 for (; aPlaneIt.More(); aPlaneIt.Next())
466 {
467 const Handle(Graphic3d_ClipPlane)& aUserPln = aPlaneIt.Value();
468 if (aUserPln->IsOn())
469 aPlanesOn.Add (aUserPln);
470 }
471
472 // set structure clipping planes
473 if (aPlanesOn.Size() > 0)
474 {
475 aContext->ChangeClipping().Set (aPlanesOn, AWorkspace->ViewMatrix());
476 }
477
2166f0fa
SK
478 // Render groups
479 OpenGl_ListOfGroup::Iterator itg(myGroups);
480 while (itg.More())
481 {
482 itg.Value()->Render(AWorkspace);
483 itg.Next();
484 }
485
4269bd1b 486 // Render cappings for structure groups
487 OpenGl_CappingAlgo::RenderCapping (AWorkspace, myGroups);
488
489 // unset structure clipping planes
490 if (aPlanesOn.Size() > 0)
491 {
492 aContext->ChangeClipping().Unset (aPlanesOn);
493 }
494
2166f0fa
SK
495 // Restore highlight color
496 AWorkspace->HighlightColor = highlight_color;
497
498 // Restore aspects
499 AWorkspace->SetAspectLine(aspect_line);
500 AWorkspace->SetAspectFace(aspect_face);
501 AWorkspace->SetAspectMarker(aspect_marker);
502 AWorkspace->SetAspectText(aspect_text);
503
504 // Restore transform persistence
505 if ( myTransPers && myTransPers->mode != 0 )
506 {
507 AWorkspace->ActiveView()->BeginTransformPersistence( trans_pers );
508 }
509
510 // Restore local transformation
511 if (myTransformation)
512 {
513 if (isImmediate)
514 {
515 glPopMatrix ();
516 glMatrixMode (matrix_mode);
517 }
518 else
519 {
520 AWorkspace->SetStructureMatrix(local_trsf);
521
522 glMatrixMode (GL_MODELVIEW);
523 glPopMatrix();
524 }
525 }
526
527 // Restore named status
528 AWorkspace->NamedStatus = named_status;
529}
530
5e27df78 531// =======================================================================
532// function : Release
533// purpose :
534// =======================================================================
535void OpenGl_Structure::Release (const Handle(OpenGl_Context)& theGlCtx)
536{
537 // Release groups
538 Clear (theGlCtx);
539 OpenGl_Element::Destroy (theGlCtx, myAspectLine);
540 OpenGl_Element::Destroy (theGlCtx, myAspectFace);
541 OpenGl_Element::Destroy (theGlCtx, myAspectMarker);
542 OpenGl_Element::Destroy (theGlCtx, myAspectText);
543 ClearHighlightColor (theGlCtx);
544}
545
dd8a4ce9 546// =======================================================================
547// function : ReleaseGlResources
548// purpose :
549// =======================================================================
550void OpenGl_Structure::ReleaseGlResources (const Handle(OpenGl_Context)& theGlCtx)
551{
552 for (OpenGl_ListOfGroup::Iterator anIter (myGroups); anIter.More(); anIter.Next())
553 {
554 OpenGl_Group* aGroup = const_cast<OpenGl_Group*& > (anIter.ChangeValue());
555 if (aGroup != NULL)
556 {
557 aGroup->Release (theGlCtx);
558 }
559 }
560 if (myAspectLine != NULL)
561 {
562 myAspectLine->Release (theGlCtx);
563 }
564 if (myAspectFace != NULL)
565 {
566 myAspectFace->Release (theGlCtx);
567 }
568 if (myAspectMarker != NULL)
569 {
570 myAspectMarker->Release (theGlCtx);
571 }
572 if (myAspectText != NULL)
573 {
574 myAspectText->Release (theGlCtx);
575 }
576 if (myHighlightBox != NULL)
577 {
578 myHighlightBox->Release (theGlCtx);
579 }
580}
581
59f45b7c 582//=======================================================================
583//function : SetZLayer
bf75be98 584//purpose :
59f45b7c 585//=======================================================================
59f45b7c 586void OpenGl_Structure::SetZLayer (const Standard_Integer theLayerIndex)
587{
588 myZLayer = theLayerIndex;
589}
590
591//=======================================================================
592//function : GetZLayer
bf75be98 593//purpose :
59f45b7c 594//=======================================================================
59f45b7c 595Standard_Integer OpenGl_Structure::GetZLayer () const
596{
597 return myZLayer;
598}