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