1 // Created on: 2011-08-01
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2012 OPEN CASCADE SAS
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.
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.
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.
20 #include <OpenGl_GlCore11.hxx>
22 #include <OpenGl_Structure.hxx>
24 #include <OpenGl_Workspace.hxx>
25 #include <OpenGl_Vec.hxx>
26 #include <OpenGl_View.hxx>
27 #include <OpenGl_CappingAlgo.hxx>
28 #include <OpenGl_Context.hxx>
29 #include <OpenGl_telem_util.hxx>
31 #include <Graphic3d_SetOfHClipPlane_Handle.hxx>
33 //! Auxiliary class for bounding box presentation
34 class OpenGl_BndBoxPrs : public OpenGl_Element
40 OpenGl_BndBoxPrs (const CALL_DEF_BOUNDBOX& theBndBox)
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);
66 //! Render presentation
67 virtual void Render (const Handle(OpenGl_Workspace)& theWorkspace) const
70 const OpenGl_AspectLine* anAspectLine = theWorkspace->AspectLine (Standard_True);
71 const Handle(OpenGl_Texture) aPrevTexture = theWorkspace->DisableTexture();
73 glDisable (GL_LIGHTING);
74 if ((theWorkspace->NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE)) != 0)
76 glDepthMask (GL_FALSE);
79 // Use highlight colors
80 glColor3fv ((theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT) ? theWorkspace->HighlightColor->rgb : anAspectLine->Color().rgb);
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);
88 if (!aPrevTexture.IsNull())
90 theWorkspace->EnableTexture (aPrevTexture);
94 //! Release graphical resources
95 virtual void Release (const Handle(OpenGl_Context)& )
102 //! Protected destructor
103 virtual ~OpenGl_BndBoxPrs() {}
107 OpenGl_Vec3 myVerts[16]; //!< vertices array
111 DEFINE_STANDARD_ALLOC
115 /*----------------------------------------------------------------------*/
117 // =======================================================================
118 // function : call_util_transpose_mat
120 // =======================================================================
121 static void call_util_transpose_mat (float tmat[16], float mat[4][4])
127 tmat[j*4+i] = mat[i][j];
130 // =======================================================================
131 // function : OpenGl_Structure
133 // =======================================================================
134 OpenGl_Structure::OpenGl_Structure ()
135 : myTransformation(NULL),
139 myAspectMarker(NULL),
141 myHighlightBox(NULL),
142 myHighlightColor(NULL),
148 // =======================================================================
149 // function : ~OpenGl_Structure
151 // =======================================================================
152 OpenGl_Structure::~OpenGl_Structure()
154 Release (Handle(OpenGl_Context)());
155 delete myTransformation; myTransformation = NULL;
156 delete myTransPers; myTransPers = NULL;
159 // =======================================================================
160 // function : SetTransformation
162 // =======================================================================
163 void OpenGl_Structure::SetTransformation(const float *AMatrix)
165 if (!myTransformation)
166 myTransformation = new OpenGl_Matrix();
168 matcpy( myTransformation->mat, AMatrix );
171 // =======================================================================
172 // function : SetTransformPersistence
174 // =======================================================================
175 void OpenGl_Structure::SetTransformPersistence(const CALL_DEF_TRANSFORM_PERSISTENCE &ATransPers)
178 myTransPers = new TEL_TRANSFORM_PERSISTENCE;
180 myTransPers->mode = ATransPers.Flag;
181 myTransPers->pointX = ATransPers.Point.x;
182 myTransPers->pointY = ATransPers.Point.y;
183 myTransPers->pointZ = ATransPers.Point.z;
186 // =======================================================================
187 // function : SetAspectLine
189 // =======================================================================
190 void OpenGl_Structure::SetAspectLine (const CALL_DEF_CONTEXTLINE &AContext)
193 myAspectLine = new OpenGl_AspectLine();
194 myAspectLine->SetContext( AContext );
197 // =======================================================================
198 // function : SetAspectFace
200 // =======================================================================
201 void OpenGl_Structure::SetAspectFace (const Handle(OpenGl_Context)& theCtx,
202 const CALL_DEF_CONTEXTFILLAREA& theAspect)
206 myAspectFace = new OpenGl_AspectFace();
208 myAspectFace->Init (theCtx, theAspect);
211 // =======================================================================
212 // function : SetAspectMarker
214 // =======================================================================
215 void OpenGl_Structure::SetAspectMarker (const Handle(OpenGl_Context)& theCtx,
216 const CALL_DEF_CONTEXTMARKER& theAspect)
220 myAspectMarker = new OpenGl_AspectMarker();
222 myAspectMarker->Init (theCtx, theAspect);
225 // =======================================================================
226 // function : SetAspectText
228 // =======================================================================
229 void OpenGl_Structure::SetAspectText (const CALL_DEF_CONTEXTTEXT &AContext)
232 myAspectText = new OpenGl_AspectText();
233 myAspectText->SetContext( AContext );
236 // =======================================================================
237 // function : SetHighlightBox
239 // =======================================================================
240 void OpenGl_Structure::SetHighlightBox (const Handle(OpenGl_Context)& theGlCtx,
241 const CALL_DEF_BOUNDBOX& theBoundBox)
243 if (myHighlightBox != NULL)
245 myHighlightBox->Release (theGlCtx);
249 myHighlightBox = new OpenGl_Group();
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);
258 OpenGl_BndBoxPrs* aBndBoxPrs = new OpenGl_BndBoxPrs (theBoundBox);
259 myHighlightBox->AddElement (TelParray, aBndBoxPrs);
262 // =======================================================================
263 // function : ClearHighlightBox
265 // =======================================================================
266 void OpenGl_Structure::ClearHighlightBox (const Handle(OpenGl_Context)& theGlCtx)
268 if (myHighlightBox != NULL)
270 OpenGl_Element::Destroy (theGlCtx, myHighlightBox);
274 // =======================================================================
275 // function : SetHighlightColor
277 // =======================================================================
278 void OpenGl_Structure::SetHighlightColor (const Handle(OpenGl_Context)& theGlCtx,
279 const Standard_ShortReal R,
280 const Standard_ShortReal G,
281 const Standard_ShortReal B)
283 ClearHighlightBox (theGlCtx);
284 if (myHighlightColor == NULL)
286 myHighlightColor = new TEL_COLOUR();
289 myHighlightColor->rgb[0] = R;
290 myHighlightColor->rgb[1] = G;
291 myHighlightColor->rgb[2] = B;
292 myHighlightColor->rgb[3] = 1.F;
295 // =======================================================================
296 // function : ClearHighlightColor
298 // =======================================================================
299 void OpenGl_Structure::ClearHighlightColor (const Handle(OpenGl_Context)& theGlCtx)
301 ClearHighlightBox(theGlCtx);
302 delete myHighlightColor;
303 myHighlightColor = NULL;
306 // =======================================================================
307 // function : Connect
309 // =======================================================================
310 void OpenGl_Structure::Connect (const OpenGl_Structure *AStructure)
312 Disconnect (AStructure);
313 myConnected.Append(AStructure);
316 // =======================================================================
317 // function : Disconnect
319 // =======================================================================
320 void OpenGl_Structure::Disconnect (const OpenGl_Structure *AStructure)
322 OpenGl_ListOfStructure::Iterator its(myConnected);
325 // Check for the given structure
326 if (its.Value() == AStructure)
328 myConnected.Remove(its);
335 // =======================================================================
336 // function : AddGroup
338 // =======================================================================
339 OpenGl_Group * OpenGl_Structure::AddGroup ()
342 OpenGl_Group *g = new OpenGl_Group;
347 // =======================================================================
348 // function : RemoveGroup
350 // =======================================================================
351 void OpenGl_Structure::RemoveGroup (const Handle(OpenGl_Context)& theGlCtx,
352 const OpenGl_Group* theGroup)
354 for (OpenGl_ListOfGroup::Iterator anIter (myGroups); anIter.More(); anIter.Next())
356 // Check for the given group
357 if (anIter.Value() == theGroup)
360 OpenGl_Element::Destroy (theGlCtx, const_cast<OpenGl_Group*& > (anIter.ChangeValue()));
361 myGroups.Remove (anIter);
367 // =======================================================================
370 // =======================================================================
371 void OpenGl_Structure::Clear (const Handle(OpenGl_Context)& theGlCtx)
374 for (OpenGl_ListOfGroup::Iterator anIter (myGroups); anIter.More(); anIter.Next())
377 OpenGl_Element::Destroy (theGlCtx, const_cast<OpenGl_Group*& > (anIter.ChangeValue()));
382 // =======================================================================
385 // =======================================================================
386 void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
388 // Process the structure only if visible
389 if ( myNamedStatus & OPENGL_NS_HIDE )
392 // Render named status
393 const Standard_Integer named_status = AWorkspace->NamedStatus;
394 AWorkspace->NamedStatus |= myNamedStatus;
396 // Is rendering in ADD or IMMEDIATE mode?
397 const Standard_Boolean isImmediate = (AWorkspace->NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE)) != 0;
399 // Apply local transformation
400 GLint matrix_mode = 0;
401 const OpenGl_Matrix *local_trsf = NULL;
402 if (myTransformation)
407 call_util_transpose_mat (mat16, myTransformation->mat);
408 glGetIntegerv (GL_MATRIX_MODE, &matrix_mode);
409 glMatrixMode (GL_MODELVIEW);
411 glScalef (1.F, 1.F, 1.F);
412 glMultMatrixf (mat16);
416 glMatrixMode (GL_MODELVIEW);
419 local_trsf = AWorkspace->SetStructureMatrix(myTransformation);
423 // Apply transform persistence
424 const TEL_TRANSFORM_PERSISTENCE *trans_pers = NULL;
425 if ( myTransPers && myTransPers->mode != 0 )
427 trans_pers = AWorkspace->ActiveView()->BeginTransformPersistence( myTransPers );
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);
436 AWorkspace->SetAspectLine(myAspectLine);
438 AWorkspace->SetAspectFace(myAspectFace);
440 AWorkspace->SetAspectMarker(myAspectMarker);
442 AWorkspace->SetAspectText(myAspectText);
444 // Apply highlight box
446 myHighlightBox->Render( AWorkspace );
448 // Apply highlight color
449 const TEL_COLOUR *highlight_color = AWorkspace->HighlightColor;
450 if (myHighlightColor)
451 AWorkspace->HighlightColor = myHighlightColor;
453 // Render connected structures
454 OpenGl_ListOfStructure::Iterator its(myConnected);
457 its.Value()->Render(AWorkspace);
461 // Set up plane equations for non-structure transformed global model-view matrix
462 const Handle(OpenGl_Context)& aContext = AWorkspace->GetGlContext();
464 // List of planes to be applied to context state
465 Handle(Graphic3d_SetOfHClipPlane) aUserPlanes;
467 // Collect clipping planes of structure scope
468 if (!myClipPlanes.IsEmpty())
470 Graphic3d_SetOfHClipPlane::Iterator aClippingIt (myClipPlanes);
471 for (; aClippingIt.More(); aClippingIt.Next())
473 const Handle(Graphic3d_ClipPlane)& aClipPlane = aClippingIt.Value();
474 if (!aClipPlane->IsOn())
479 if (aUserPlanes.IsNull())
481 aUserPlanes = new Graphic3d_SetOfHClipPlane();
484 aUserPlanes->Add (aClipPlane);
488 if (!aUserPlanes.IsNull() && !aUserPlanes->IsEmpty())
490 // add planes at loaded view matrix state
491 aContext->ChangeClipping().AddWorld (*aUserPlanes, AWorkspace);
495 OpenGl_ListOfGroup::Iterator itg(myGroups);
498 itg.Value()->Render(AWorkspace);
502 // Render capping for structure groups
503 if (!aContext->Clipping().Planes().IsEmpty())
505 OpenGl_CappingAlgo::RenderCapping (AWorkspace, myGroups);
508 // Revert structure clippings
509 if (!aUserPlanes.IsNull() && !aUserPlanes->IsEmpty())
511 aContext->ChangeClipping().Remove (*aUserPlanes);
514 // Restore highlight color
515 AWorkspace->HighlightColor = highlight_color;
518 AWorkspace->SetAspectLine(aspect_line);
519 AWorkspace->SetAspectFace(aspect_face);
520 AWorkspace->SetAspectMarker(aspect_marker);
521 AWorkspace->SetAspectText(aspect_text);
523 // Restore transform persistence
524 if ( myTransPers && myTransPers->mode != 0 )
526 AWorkspace->ActiveView()->BeginTransformPersistence( trans_pers );
529 // Restore local transformation
530 if (myTransformation)
535 glMatrixMode (matrix_mode);
539 AWorkspace->SetStructureMatrix(local_trsf);
541 glMatrixMode (GL_MODELVIEW);
546 // Restore named status
547 AWorkspace->NamedStatus = named_status;
550 // =======================================================================
551 // function : Release
553 // =======================================================================
554 void OpenGl_Structure::Release (const Handle(OpenGl_Context)& 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);
565 // =======================================================================
566 // function : ReleaseGlResources
568 // =======================================================================
569 void OpenGl_Structure::ReleaseGlResources (const Handle(OpenGl_Context)& theGlCtx)
571 for (OpenGl_ListOfGroup::Iterator anIter (myGroups); anIter.More(); anIter.Next())
573 OpenGl_Group* aGroup = const_cast<OpenGl_Group*& > (anIter.ChangeValue());
576 aGroup->Release (theGlCtx);
579 if (myAspectLine != NULL)
581 myAspectLine->Release (theGlCtx);
583 if (myAspectFace != NULL)
585 myAspectFace->Release (theGlCtx);
587 if (myAspectMarker != NULL)
589 myAspectMarker->Release (theGlCtx);
591 if (myAspectText != NULL)
593 myAspectText->Release (theGlCtx);
595 if (myHighlightBox != NULL)
597 myHighlightBox->Release (theGlCtx);
601 //=======================================================================
602 //function : SetZLayer
604 //=======================================================================
605 void OpenGl_Structure::SetZLayer (const Standard_Integer theLayerIndex)
607 myZLayer = theLayerIndex;
610 //=======================================================================
611 //function : GetZLayer
613 //=======================================================================
614 Standard_Integer OpenGl_Structure::GetZLayer () const