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 //! Auxiliary class for bounding box presentation
32 class OpenGl_BndBoxPrs : public OpenGl_Element
38 OpenGl_BndBoxPrs (const CALL_DEF_BOUNDBOX& theBndBox)
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);
64 //! Render presentation
65 virtual void Render (const Handle(OpenGl_Workspace)& theWorkspace) const
68 const OpenGl_AspectLine* anAspectLine = theWorkspace->AspectLine (Standard_True);
69 const Handle(OpenGl_Texture) aPrevTexture = theWorkspace->DisableTexture();
71 glDisable (GL_LIGHTING);
72 if ((theWorkspace->NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE)) != 0)
74 glDepthMask (GL_FALSE);
77 // Use highlight colors
78 glColor3fv ((theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT) ? theWorkspace->HighlightColor->rgb : anAspectLine->Color().rgb);
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);
86 if (!aPrevTexture.IsNull())
88 theWorkspace->EnableTexture (aPrevTexture);
92 //! Release graphical resources
93 virtual void Release (const Handle(OpenGl_Context)& )
100 //! Protected destructor
101 virtual ~OpenGl_BndBoxPrs() {}
105 OpenGl_Vec3 myVerts[16]; //!< vertices array
109 DEFINE_STANDARD_ALLOC
113 /*----------------------------------------------------------------------*/
115 // =======================================================================
116 // function : call_util_transpose_mat
118 // =======================================================================
119 static void call_util_transpose_mat (float tmat[16], float mat[4][4])
125 tmat[j*4+i] = mat[i][j];
128 // =======================================================================
129 // function : OpenGl_Structure
131 // =======================================================================
132 OpenGl_Structure::OpenGl_Structure ()
133 : myTransformation(NULL),
137 myAspectMarker(NULL),
139 myHighlightBox(NULL),
140 myHighlightColor(NULL),
146 // =======================================================================
147 // function : ~OpenGl_Structure
149 // =======================================================================
150 OpenGl_Structure::~OpenGl_Structure()
152 Release (Handle(OpenGl_Context)());
153 delete myTransformation; myTransformation = NULL;
154 delete myTransPers; myTransPers = NULL;
157 // =======================================================================
158 // function : SetTransformation
160 // =======================================================================
161 void OpenGl_Structure::SetTransformation(const float *AMatrix)
163 if (!myTransformation)
164 myTransformation = new OpenGl_Matrix();
166 matcpy( myTransformation->mat, AMatrix );
169 // =======================================================================
170 // function : SetTransformPersistence
172 // =======================================================================
173 void OpenGl_Structure::SetTransformPersistence(const CALL_DEF_TRANSFORM_PERSISTENCE &ATransPers)
176 myTransPers = new TEL_TRANSFORM_PERSISTENCE;
178 myTransPers->mode = ATransPers.Flag;
179 myTransPers->pointX = ATransPers.Point.x;
180 myTransPers->pointY = ATransPers.Point.y;
181 myTransPers->pointZ = ATransPers.Point.z;
184 // =======================================================================
185 // function : SetAspectLine
187 // =======================================================================
188 void OpenGl_Structure::SetAspectLine (const CALL_DEF_CONTEXTLINE &AContext)
191 myAspectLine = new OpenGl_AspectLine();
192 myAspectLine->SetContext( AContext );
195 // =======================================================================
196 // function : SetAspectFace
198 // =======================================================================
199 void OpenGl_Structure::SetAspectFace (const Handle(OpenGl_Context)& theCtx,
200 const CALL_DEF_CONTEXTFILLAREA& theAspect)
204 myAspectFace = new OpenGl_AspectFace();
206 myAspectFace->Init (theCtx, theAspect);
209 // =======================================================================
210 // function : SetAspectMarker
212 // =======================================================================
213 void OpenGl_Structure::SetAspectMarker (const Handle(OpenGl_Context)& theCtx,
214 const CALL_DEF_CONTEXTMARKER& theAspect)
218 myAspectMarker = new OpenGl_AspectMarker();
220 myAspectMarker->Init (theCtx, theAspect);
223 // =======================================================================
224 // function : SetAspectText
226 // =======================================================================
227 void OpenGl_Structure::SetAspectText (const CALL_DEF_CONTEXTTEXT &AContext)
230 myAspectText = new OpenGl_AspectText();
231 myAspectText->SetContext( AContext );
234 // =======================================================================
235 // function : SetHighlightBox
237 // =======================================================================
238 void OpenGl_Structure::SetHighlightBox (const Handle(OpenGl_Context)& theGlCtx,
239 const CALL_DEF_BOUNDBOX& theBoundBox)
241 if (myHighlightBox != NULL)
243 myHighlightBox->Release (theGlCtx);
247 myHighlightBox = new OpenGl_Group();
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);
256 OpenGl_BndBoxPrs* aBndBoxPrs = new OpenGl_BndBoxPrs (theBoundBox);
257 myHighlightBox->AddElement (TelParray, aBndBoxPrs);
260 // =======================================================================
261 // function : ClearHighlightBox
263 // =======================================================================
264 void OpenGl_Structure::ClearHighlightBox (const Handle(OpenGl_Context)& theGlCtx)
266 if (myHighlightBox != NULL)
268 OpenGl_Element::Destroy (theGlCtx, myHighlightBox);
272 // =======================================================================
273 // function : SetHighlightColor
275 // =======================================================================
276 void OpenGl_Structure::SetHighlightColor (const Handle(OpenGl_Context)& theGlCtx,
277 const Standard_ShortReal R,
278 const Standard_ShortReal G,
279 const Standard_ShortReal B)
281 ClearHighlightBox (theGlCtx);
282 if (myHighlightColor == NULL)
284 myHighlightColor = new TEL_COLOUR();
287 myHighlightColor->rgb[0] = R;
288 myHighlightColor->rgb[1] = G;
289 myHighlightColor->rgb[2] = B;
290 myHighlightColor->rgb[3] = 1.F;
293 // =======================================================================
294 // function : ClearHighlightColor
296 // =======================================================================
297 void OpenGl_Structure::ClearHighlightColor (const Handle(OpenGl_Context)& theGlCtx)
299 ClearHighlightBox(theGlCtx);
300 delete myHighlightColor;
301 myHighlightColor = NULL;
304 // =======================================================================
305 // function : Connect
307 // =======================================================================
308 void OpenGl_Structure::Connect (const OpenGl_Structure *AStructure)
310 Disconnect (AStructure);
311 myConnected.Append(AStructure);
314 // =======================================================================
315 // function : Disconnect
317 // =======================================================================
318 void OpenGl_Structure::Disconnect (const OpenGl_Structure *AStructure)
320 OpenGl_ListOfStructure::Iterator its(myConnected);
323 // Check for the given structure
324 if (its.Value() == AStructure)
326 myConnected.Remove(its);
333 // =======================================================================
334 // function : AddGroup
336 // =======================================================================
337 OpenGl_Group * OpenGl_Structure::AddGroup ()
340 OpenGl_Group *g = new OpenGl_Group;
345 // =======================================================================
346 // function : RemoveGroup
348 // =======================================================================
349 void OpenGl_Structure::RemoveGroup (const Handle(OpenGl_Context)& theGlCtx,
350 const OpenGl_Group* theGroup)
352 for (OpenGl_ListOfGroup::Iterator anIter (myGroups); anIter.More(); anIter.Next())
354 // Check for the given group
355 if (anIter.Value() == theGroup)
358 OpenGl_Element::Destroy (theGlCtx, const_cast<OpenGl_Group*& > (anIter.ChangeValue()));
359 myGroups.Remove (anIter);
365 // =======================================================================
368 // =======================================================================
369 void OpenGl_Structure::Clear (const Handle(OpenGl_Context)& theGlCtx)
372 for (OpenGl_ListOfGroup::Iterator anIter (myGroups); anIter.More(); anIter.Next())
375 OpenGl_Element::Destroy (theGlCtx, const_cast<OpenGl_Group*& > (anIter.ChangeValue()));
380 // =======================================================================
383 // =======================================================================
384 void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
386 // Process the structure only if visible
387 if ( myNamedStatus & OPENGL_NS_HIDE )
390 // Render named status
391 const Standard_Integer named_status = AWorkspace->NamedStatus;
392 AWorkspace->NamedStatus |= myNamedStatus;
394 // Is rendering in ADD or IMMEDIATE mode?
395 const Standard_Boolean isImmediate = (AWorkspace->NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE)) != 0;
397 // Apply local transformation
398 GLint matrix_mode = 0;
399 const OpenGl_Matrix *local_trsf = NULL;
400 if (myTransformation)
405 call_util_transpose_mat (mat16, myTransformation->mat);
406 glGetIntegerv (GL_MATRIX_MODE, &matrix_mode);
407 glMatrixMode (GL_MODELVIEW);
409 glScalef (1.F, 1.F, 1.F);
410 glMultMatrixf (mat16);
414 glMatrixMode (GL_MODELVIEW);
417 local_trsf = AWorkspace->SetStructureMatrix(myTransformation);
421 // Apply transform persistence
422 const TEL_TRANSFORM_PERSISTENCE *trans_pers = NULL;
423 if ( myTransPers && myTransPers->mode != 0 )
425 trans_pers = AWorkspace->ActiveView()->BeginTransformPersistence( myTransPers );
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);
434 AWorkspace->SetAspectLine(myAspectLine);
436 AWorkspace->SetAspectFace(myAspectFace);
438 AWorkspace->SetAspectMarker(myAspectMarker);
440 AWorkspace->SetAspectText(myAspectText);
442 // Apply highlight box
444 myHighlightBox->Render( AWorkspace );
446 // Apply highlight color
447 const TEL_COLOUR *highlight_color = AWorkspace->HighlightColor;
448 if (myHighlightColor)
449 AWorkspace->HighlightColor = myHighlightColor;
451 // Render connected structures
452 OpenGl_ListOfStructure::Iterator its(myConnected);
455 its.Value()->Render(AWorkspace);
459 // Set up plane equations for non-structure transformed global model-view matrix
460 const Handle(OpenGl_Context)& aContext = AWorkspace->GetGlContext();
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())
467 const Handle(Graphic3d_ClipPlane)& aUserPln = aPlaneIt.Value();
468 if (aUserPln->IsOn())
469 aPlanesOn.Add (aUserPln);
472 // set structure clipping planes
473 if (aPlanesOn.Size() > 0)
475 aContext->ChangeClipping().Set (aPlanesOn, AWorkspace->ViewMatrix());
479 OpenGl_ListOfGroup::Iterator itg(myGroups);
482 itg.Value()->Render(AWorkspace);
486 // Render cappings for structure groups
487 OpenGl_CappingAlgo::RenderCapping (AWorkspace, myGroups);
489 // unset structure clipping planes
490 if (aPlanesOn.Size() > 0)
492 aContext->ChangeClipping().Unset (aPlanesOn);
495 // Restore highlight color
496 AWorkspace->HighlightColor = highlight_color;
499 AWorkspace->SetAspectLine(aspect_line);
500 AWorkspace->SetAspectFace(aspect_face);
501 AWorkspace->SetAspectMarker(aspect_marker);
502 AWorkspace->SetAspectText(aspect_text);
504 // Restore transform persistence
505 if ( myTransPers && myTransPers->mode != 0 )
507 AWorkspace->ActiveView()->BeginTransformPersistence( trans_pers );
510 // Restore local transformation
511 if (myTransformation)
516 glMatrixMode (matrix_mode);
520 AWorkspace->SetStructureMatrix(local_trsf);
522 glMatrixMode (GL_MODELVIEW);
527 // Restore named status
528 AWorkspace->NamedStatus = named_status;
531 // =======================================================================
532 // function : Release
534 // =======================================================================
535 void OpenGl_Structure::Release (const Handle(OpenGl_Context)& 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);
546 // =======================================================================
547 // function : ReleaseGlResources
549 // =======================================================================
550 void OpenGl_Structure::ReleaseGlResources (const Handle(OpenGl_Context)& theGlCtx)
552 for (OpenGl_ListOfGroup::Iterator anIter (myGroups); anIter.More(); anIter.Next())
554 OpenGl_Group* aGroup = const_cast<OpenGl_Group*& > (anIter.ChangeValue());
557 aGroup->Release (theGlCtx);
560 if (myAspectLine != NULL)
562 myAspectLine->Release (theGlCtx);
564 if (myAspectFace != NULL)
566 myAspectFace->Release (theGlCtx);
568 if (myAspectMarker != NULL)
570 myAspectMarker->Release (theGlCtx);
572 if (myAspectText != NULL)
574 myAspectText->Release (theGlCtx);
576 if (myHighlightBox != NULL)
578 myHighlightBox->Release (theGlCtx);
582 //=======================================================================
583 //function : SetZLayer
585 //=======================================================================
586 void OpenGl_Structure::SetZLayer (const Standard_Integer theLayerIndex)
588 myZLayer = theLayerIndex;
591 //=======================================================================
592 //function : GetZLayer
594 //=======================================================================
595 Standard_Integer OpenGl_Structure::GetZLayer () const