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