94b165786ef2f16d859ce8ce17a0a5c536dacaf6
[occt.git] / src / OpenGl / OpenGl_Structure.cxx
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
20
21 #include <OpenGl_GlCore11.hxx>
22
23 #include <OpenGl_Structure.hxx>
24
25 #include <OpenGl_Polyline.hxx>
26 #include <OpenGl_Workspace.hxx>
27 #include <OpenGl_View.hxx>
28
29 #include <OpenGl_telem_util.hxx>
30
31
32 /*----------------------------------------------------------------------*/
33
34 static void call_util_transpose_mat (float tmat[16], float mat[4][4])
35 {
36   int i, j;
37
38   for (i=0; i<4; i++)
39     for (j=0; j<4; j++)
40       tmat[j*4+i] = mat[i][j];
41 }
42
43 /*----------------------------------------------------------------------*/
44
45 OpenGl_Structure::OpenGl_Structure ()
46 : myTransformation(NULL),
47   myTransPers(NULL),
48   myDegenerateModel(NULL),
49   myAspectLine(NULL),
50   myAspectFace(NULL),
51   myAspectMarker(NULL),
52   myAspectText(NULL),
53   myHighlightBox(NULL),
54   myHighlightColor(NULL),
55   myNamedStatus(0),
56   myZLayer(0)
57 {
58 }
59
60 /*----------------------------------------------------------------------*/
61
62 OpenGl_Structure::~OpenGl_Structure ()
63 {
64   if (myTransformation)
65   {
66     delete myTransformation;
67     myTransformation = NULL;
68   }
69   if (myTransPers)
70   {
71     delete myTransPers;
72     myTransPers = NULL;
73   }
74   if (myDegenerateModel)
75   {
76     delete myDegenerateModel;
77     myDegenerateModel = NULL;
78   }
79   if (myAspectLine)
80   {
81     delete myAspectLine;
82     myAspectLine = NULL;
83   }
84   if (myAspectFace)
85   {
86     delete myAspectFace;
87     myAspectFace = NULL;
88   }
89   if (myAspectMarker)
90   {
91     delete myAspectMarker;
92     myAspectMarker = NULL;
93   }
94   if (myAspectText)
95   {
96     delete myAspectText;
97     myAspectText = NULL;
98   }
99   ClearHighlightColor();
100   // Delete groups
101   Clear();
102 }
103
104 /*----------------------------------------------------------------------*/
105
106 void OpenGl_Structure::SetTransformation(const float *AMatrix)
107 {
108   if (!myTransformation)
109     myTransformation = new OpenGl_Matrix;
110
111   matcpy( myTransformation->mat, AMatrix );
112 }
113
114 /*----------------------------------------------------------------------*/
115
116 void OpenGl_Structure::SetTransformPersistence(const CALL_DEF_TRANSFORM_PERSISTENCE &ATransPers)
117 {
118   if (!myTransPers)
119     myTransPers = new TEL_TRANSFORM_PERSISTENCE;
120
121   myTransPers->mode = ATransPers.Flag;
122   myTransPers->pointX = ATransPers.Point.x;
123   myTransPers->pointY = ATransPers.Point.y;
124   myTransPers->pointZ = ATransPers.Point.z;
125 }
126
127 /*----------------------------------------------------------------------*/
128
129 void OpenGl_Structure::SetDegenerateModel (const Standard_Integer AMode, const float ASkipRatio)
130 {
131   if (!myDegenerateModel)
132     myDegenerateModel = new DEGENERATION;
133
134   myDegenerateModel->mode = AMode;
135   myDegenerateModel->skipRatio = ASkipRatio;
136 }
137
138 /*----------------------------------------------------------------------*/
139
140 void OpenGl_Structure::SetAspectLine (const CALL_DEF_CONTEXTLINE &AContext)
141 {
142   if (!myAspectLine)
143     myAspectLine = new OpenGl_AspectLine;
144   myAspectLine->SetContext( AContext );
145 }
146
147 /*----------------------------------------------------------------------*/
148
149 void OpenGl_Structure::SetAspectFace (const CALL_DEF_CONTEXTFILLAREA &AContext)
150 {
151   if (!myAspectFace)
152     myAspectFace = new OpenGl_AspectFace;
153   myAspectFace->SetContext( AContext );
154 }
155
156 /*----------------------------------------------------------------------*/
157
158 void OpenGl_Structure::SetAspectMarker (const CALL_DEF_CONTEXTMARKER &AContext)
159 {
160   if (!myAspectMarker)
161     myAspectMarker = new OpenGl_AspectMarker;
162   myAspectMarker->SetContext( AContext );
163 }
164
165 /*----------------------------------------------------------------------*/
166
167 void OpenGl_Structure::SetAspectText (const CALL_DEF_CONTEXTTEXT &AContext)
168 {
169   if (!myAspectText)
170     myAspectText = new OpenGl_AspectText;
171   myAspectText->SetContext( AContext );
172 }
173
174 /*----------------------------------------------------------------------*/
175
176 void OpenGl_Structure::SetHighlightBox (const CALL_DEF_BOUNDBOX &ABoundBox)
177 {
178   if (!myHighlightBox)
179     myHighlightBox = new OpenGl_Group;
180   else
181     myHighlightBox->Clear();
182
183   CALL_DEF_CONTEXTLINE context_line;
184   context_line.Color = ABoundBox.Color;
185   context_line.LineType = Aspect_TOL_SOLID;
186   context_line.Width = 1.0f;
187   myHighlightBox->SetAspectLine( context_line );
188
189 #define CALL_MAX_BOUNDBOXSIZE 16
190
191   Graphic3d_Array1OfVertex points(1,CALL_MAX_BOUNDBOXSIZE);
192   const float Xm = ABoundBox.Pmin.x;
193   const float Ym = ABoundBox.Pmin.y;
194   const float Zm = ABoundBox.Pmin.z;
195   const float XM = ABoundBox.Pmax.x;
196   const float YM = ABoundBox.Pmax.y;
197   const float ZM = ABoundBox.Pmax.z;
198   points( 1).SetCoord(Xm,Ym,Zm);
199   points( 2).SetCoord(Xm,Ym,ZM);
200   points( 3).SetCoord(Xm,YM,ZM);
201   points( 4).SetCoord(Xm,YM,Zm);
202   points( 5).SetCoord(Xm,Ym,Zm);
203   points( 6).SetCoord(XM,Ym,Zm);
204   points( 7).SetCoord(XM,Ym,ZM);
205   points( 8).SetCoord(XM,YM,ZM);
206   points( 9).SetCoord(XM,YM,Zm);
207   points(10).SetCoord(XM,Ym,Zm);
208   points(11).SetCoord(XM,YM,Zm);
209   points(12).SetCoord(Xm,YM,Zm);
210   points(13).SetCoord(Xm,YM,ZM);
211   points(14).SetCoord(XM,YM,ZM);
212   points(15).SetCoord(XM,Ym,ZM);
213   points(16).SetCoord(Xm,Ym,ZM);
214
215   OpenGl_Polyline *apolyline = new OpenGl_Polyline(points);
216   myHighlightBox->AddElement( TelPolyline, apolyline );
217 }
218
219 /*----------------------------------------------------------------------*/
220
221 void OpenGl_Structure::ClearHighlightBox ()
222 {
223   if (myHighlightBox)
224   {
225     delete myHighlightBox;
226     myHighlightBox = NULL;
227   }
228 }
229
230 /*----------------------------------------------------------------------*/
231
232 void OpenGl_Structure::SetHighlightColor (const Standard_ShortReal R, const Standard_ShortReal G, const Standard_ShortReal B)
233 {
234   ClearHighlightBox();
235   if (!myHighlightColor)
236     myHighlightColor = new TEL_COLOUR;
237
238   myHighlightColor->rgb[0] = R;
239   myHighlightColor->rgb[1] = G;
240   myHighlightColor->rgb[2] = B;
241   myHighlightColor->rgb[3] = 1.F;
242 }
243
244 /*----------------------------------------------------------------------*/
245
246 void OpenGl_Structure::ClearHighlightColor ()
247 {
248   ClearHighlightBox();
249   if (myHighlightColor)
250   {
251     delete myHighlightColor;
252     myHighlightColor = NULL;
253   }
254 }
255
256 /*----------------------------------------------------------------------*/
257
258 void OpenGl_Structure::Connect (const OpenGl_Structure *AStructure)
259 {
260   Disconnect (AStructure);
261   myConnected.Append(AStructure);
262 }
263
264 /*----------------------------------------------------------------------*/
265
266 void OpenGl_Structure::Disconnect (const OpenGl_Structure *AStructure)
267 {
268   OpenGl_ListOfStructure::Iterator its(myConnected);
269   while (its.More())
270   {
271     // Check for the given structure
272     if (its.Value() == AStructure)
273     {
274       myConnected.Remove(its);
275       return;
276     }
277     its.Next();
278   }
279 }
280
281 /*----------------------------------------------------------------------*/
282
283 OpenGl_Group * OpenGl_Structure::AddGroup ()
284 {
285   // Create new group
286   OpenGl_Group *g = new OpenGl_Group;
287   myGroups.Append(g);
288   return g;
289 }
290
291 /*----------------------------------------------------------------------*/
292
293 void OpenGl_Structure::RemoveGroup (const OpenGl_Group *AGroup)
294 {
295   OpenGl_ListOfGroup::Iterator itg(myGroups);
296   while (itg.More())
297   {
298     // Check for the given group
299     if (itg.Value() == AGroup)
300     {
301       // Delete object
302       delete AGroup;
303       myGroups.Remove(itg);
304       return;
305     }
306     itg.Next();
307   }
308 }
309
310 /*----------------------------------------------------------------------*/
311
312 void OpenGl_Structure::Clear ()
313 {
314   OpenGl_ListOfGroup::Iterator itg(myGroups);
315   while (itg.More())
316   {
317     // Delete objects
318     delete itg.Value();
319     itg.Next();
320   }
321   myGroups.Clear();
322 }
323
324 /*----------------------------------------------------------------------*/
325
326 void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
327 {
328   // Process the structure only if visible
329   if ( myNamedStatus & OPENGL_NS_HIDE )
330     return;
331
332   // Render named status
333   const Standard_Integer named_status = AWorkspace->NamedStatus;
334   AWorkspace->NamedStatus |= myNamedStatus;
335
336   // Is rendering in ADD or IMMEDIATE mode?
337   const Standard_Boolean isImmediate = (AWorkspace->NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE)) != 0;
338
339   // Apply local transformation
340   GLint matrix_mode = 0;
341   const OpenGl_Matrix *local_trsf = NULL;
342   if (myTransformation)
343   {
344     if (isImmediate)
345     {
346       float mat16[16];
347       call_util_transpose_mat (mat16, myTransformation->mat);
348       glGetIntegerv (GL_MATRIX_MODE, &matrix_mode);
349       glMatrixMode (GL_MODELVIEW);
350       glPushMatrix ();
351       glScalef (1.F, 1.F, 1.F);
352       glMultMatrixf (mat16);
353     }
354     else
355     {
356       glMatrixMode (GL_MODELVIEW);
357       glPushMatrix();
358
359       local_trsf = AWorkspace->SetStructureMatrix(myTransformation);
360     }
361   }
362
363   // Apply transform persistence
364   const TEL_TRANSFORM_PERSISTENCE *trans_pers = NULL;
365   if ( myTransPers && myTransPers->mode != 0 )
366   {
367     trans_pers = AWorkspace->ActiveView()->BeginTransformPersistence( myTransPers );
368   }
369
370   // Apply degeneration
371   if (myDegenerateModel)
372   {
373     if ( AWorkspace->NamedStatus & OPENGL_NS_DEGENERATION )
374     {
375       AWorkspace->DegenerateModel = myDegenerateModel->mode;
376       switch ( AWorkspace->DegenerateModel )
377       {
378         case 0: break;
379
380         default:
381           glLineWidth ( 1.0 );
382           glDisable   ( GL_LINE_STIPPLE );
383
384         case 1:
385           AWorkspace->SkipRatio = myDegenerateModel->skipRatio;
386       }
387     }
388   }
389
390   // Apply aspects
391   const OpenGl_AspectLine *aspect_line = AWorkspace->AspectLine(Standard_False);
392   const OpenGl_AspectFace *aspect_face = AWorkspace->AspectFace(Standard_False);
393   const OpenGl_AspectMarker *aspect_marker = AWorkspace->AspectMarker(Standard_False);
394   const OpenGl_AspectText *aspect_text = AWorkspace->AspectText(Standard_False);
395   if (myAspectLine)
396     AWorkspace->SetAspectLine(myAspectLine);
397   if (myAspectFace)
398     AWorkspace->SetAspectFace(myAspectFace);
399   if (myAspectMarker)
400     AWorkspace->SetAspectMarker(myAspectMarker);
401   if (myAspectText)
402     AWorkspace->SetAspectText(myAspectText);
403
404   // Apply highlight box
405   if (myHighlightBox)
406     myHighlightBox->Render( AWorkspace );
407
408   // Apply highlight color
409   const TEL_COLOUR *highlight_color = AWorkspace->HighlightColor;
410   if (myHighlightColor)
411     AWorkspace->HighlightColor = myHighlightColor;
412
413   // Render connected structures
414   OpenGl_ListOfStructure::Iterator its(myConnected);
415   while (its.More())
416   {
417     its.Value()->Render(AWorkspace);
418     its.Next();
419   }
420
421   // Render groups
422   OpenGl_ListOfGroup::Iterator itg(myGroups);
423   while (itg.More())
424   {
425     itg.Value()->Render(AWorkspace);
426     itg.Next();
427   }
428
429   // Restore highlight color
430   AWorkspace->HighlightColor = highlight_color;
431
432   // Restore aspects
433   AWorkspace->SetAspectLine(aspect_line);
434   AWorkspace->SetAspectFace(aspect_face);
435   AWorkspace->SetAspectMarker(aspect_marker);
436   AWorkspace->SetAspectText(aspect_text);
437
438   // Restore transform persistence
439   if ( myTransPers && myTransPers->mode != 0 )
440   {
441     AWorkspace->ActiveView()->BeginTransformPersistence( trans_pers );
442   }
443
444   // Restore local transformation
445   if (myTransformation)
446   {
447     if (isImmediate)
448     {
449       glPopMatrix ();
450       glMatrixMode (matrix_mode);
451     }
452     else
453     {
454       AWorkspace->SetStructureMatrix(local_trsf);
455
456       glMatrixMode (GL_MODELVIEW);
457       glPopMatrix();
458     }
459   }
460
461   // Restore named status
462   AWorkspace->NamedStatus = named_status;
463 }
464
465 //=======================================================================
466 //function : SetZLayer
467 //purpose  : 
468 //=======================================================================
469
470 void OpenGl_Structure::SetZLayer (const Standard_Integer theLayerIndex)
471 {
472   myZLayer = theLayerIndex;
473 }
474
475 //=======================================================================
476 //function : GetZLayer
477 //purpose  : 
478 //=======================================================================
479
480 Standard_Integer OpenGl_Structure::GetZLayer () const
481 {
482   return myZLayer;
483 }