0eedb2df1a0696f26f98151a8919d67c83c731d8
[occt.git] / src / Graphic3d / Graphic3d_Group.cxx
1 // Created by: NW,JPB,CAL
2 // Copyright (c) 1991-1999 Matra Datavision
3 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <Graphic3d_Group.hxx>
17
18 #include <gp_Ax2.hxx>
19 #include <gp_Pnt.hxx>
20 #include <Graphic3d_ArrayOfPoints.hxx>
21 #include <Graphic3d_ArrayOfPrimitives.hxx>
22 #include <Graphic3d_AspectFillArea3d.hxx>
23 #include <Graphic3d_AspectLine3d.hxx>
24 #include <Graphic3d_AspectMarker3d.hxx>
25 #include <Graphic3d_AspectText3d.hxx>
26 #include <Graphic3d_CStructure.hxx>
27 #include <Graphic3d_GroupDefinitionError.hxx>
28 #include <Graphic3d_ShaderProgram.hxx>
29 #include <Graphic3d_Structure.hxx>
30 #include "Graphic3d_Structure.pxx"
31 #include <Graphic3d_StructureManager.hxx>
32 #include <Graphic3d_TextureMap.hxx>
33 #include <Graphic3d_TransModeFlags.hxx>
34 #include <Message.hxx>
35 #include <Message_Messenger.hxx>
36 #include <NCollection_String.hxx>
37 #include <Standard_OutOfRange.hxx>
38 #include <Standard_Type.hxx>
39 #include <TCollection_AsciiString.hxx>
40 #include <TCollection_ExtendedString.hxx>
41
42 IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_Group,MMgt_TShared)
43
44 // =======================================================================
45 // function : Graphic3d_Group
46 // purpose  :
47 // =======================================================================
48 Graphic3d_Group::Graphic3d_Group (const Handle(Graphic3d_Structure)& theStruct)
49 : myStructure     (theStruct.operator->()),
50   myIsClosed      (false),
51   myContainsFacet (false)
52 {
53   //
54 }
55
56 // =======================================================================
57 // function : ~Graphic3d_Group
58 // purpose  :
59 // =======================================================================
60 Graphic3d_Group::~Graphic3d_Group()
61 {
62   // tell graphics driver to clear internal resources of the group
63   Clear (Standard_False);
64 }
65
66 // =======================================================================
67 // function : Clear
68 // purpose  :
69 // =======================================================================
70 void Graphic3d_Group::Clear (Standard_Boolean theUpdateStructureMgr)
71 {
72   if (IsDeleted())
73   {
74     return;
75   }
76
77   myBounds.Clear();
78
79   if (myContainsFacet)
80   {
81     myStructure->GroupsWithFacet (-1);
82     myContainsFacet = false;
83   }
84
85   // clear method could be used on Graphic3d_Structure destruction,
86   // and its structure manager could be already destroyed, in that
87   // case we don't need to update it;
88   if (theUpdateStructureMgr)
89   {
90     Update();
91   }
92 }
93
94 // =======================================================================
95 // function : Remove
96 // purpose  :
97 // =======================================================================
98 void Graphic3d_Group::Remove()
99 {
100   if (IsDeleted())
101   {
102     return;
103   }
104
105   if (myContainsFacet)
106   {
107     myStructure->GroupsWithFacet (-1);
108     myContainsFacet = false;
109   }
110   myStructure->Remove (this);
111
112   Update();
113
114   myBounds.Clear();
115 }
116
117 // =======================================================================
118 // function : IsDeleted
119 // purpose  :
120 // =======================================================================
121 Standard_Boolean Graphic3d_Group::IsDeleted() const
122 {
123   return myStructure == NULL
124       || myStructure->IsDeleted();
125 }
126
127 // =======================================================================
128 // function : IsEmpty
129 // purpose  :
130 // =======================================================================
131 Standard_Boolean Graphic3d_Group::IsEmpty() const
132 {
133   if (IsDeleted())
134   {
135     return Standard_True;
136   }
137
138   return !myStructure->IsInfinite()
139       && !myBounds.IsValid();
140 }
141
142 // =======================================================================
143 // function : SetMinMaxValues
144 // purpose  :
145 // =======================================================================
146 void Graphic3d_Group::SetMinMaxValues (const Standard_Real theXMin, const Standard_Real theYMin, const Standard_Real theZMin,
147                                        const Standard_Real theXMax, const Standard_Real theYMax, const Standard_Real theZMax)
148 {
149   myBounds = Graphic3d_BndBox4f (Graphic3d_Vec4 (static_cast<Standard_ShortReal> (theXMin),
150                                                  static_cast<Standard_ShortReal> (theYMin),
151                                                  static_cast<Standard_ShortReal> (theZMin),
152                                                  1.0f),
153                                  Graphic3d_Vec4 (static_cast<Standard_ShortReal> (theXMax),
154                                                  static_cast<Standard_ShortReal> (theYMax),
155                                                  static_cast<Standard_ShortReal> (theZMax),
156                                                  1.0f));
157 }
158
159 // =======================================================================
160 // function : Structure
161 // purpose  :
162 // =======================================================================
163 Handle(Graphic3d_Structure) Graphic3d_Group::Structure() const
164 {
165   return myStructure;
166 }
167
168 // =======================================================================
169 // function : MinMaxValues
170 // purpose  :
171 // =======================================================================
172 void Graphic3d_Group::MinMaxValues (Standard_Real& theXMin, Standard_Real& theYMin, Standard_Real& theZMin,
173                                     Standard_Real& theXMax, Standard_Real& theYMax, Standard_Real& theZMax) const
174 {
175   if (IsEmpty())
176   {
177     // Empty Group
178     theXMin = theYMin = theZMin = ShortRealFirst();
179     theXMax = theYMax = theZMax = ShortRealLast();
180   }
181   else if (myBounds.IsValid())
182   {
183     const Graphic3d_Vec4& aMinPt = myBounds.CornerMin();
184     const Graphic3d_Vec4& aMaxPt = myBounds.CornerMax();
185     theXMin = Standard_Real (aMinPt.x());
186     theYMin = Standard_Real (aMinPt.y());
187     theZMin = Standard_Real (aMinPt.z());
188     theXMax = Standard_Real (aMaxPt.x());
189     theYMax = Standard_Real (aMaxPt.y());
190     theZMax = Standard_Real (aMaxPt.z());
191   }
192   else
193   {
194     // for consistency with old API
195     theXMin = theYMin = theZMin = ShortRealLast();
196     theXMax = theYMax = theZMax = ShortRealFirst();
197   }
198 }
199
200 // =======================================================================
201 // function : Update
202 // purpose  :
203 // =======================================================================
204 void Graphic3d_Group::Update() const
205 {
206   if (IsDeleted())
207   {
208     return;
209   }
210
211   myStructure->StructureManager()->Update (myStructure->StructureManager()->UpdateMode());
212 }
213
214 // =======================================================================
215 // function : IsGroupPrimitivesAspectSet
216 // purpose  :
217 // =======================================================================
218 Standard_Boolean Graphic3d_Group::IsGroupPrimitivesAspectSet (const Graphic3d_GroupAspect theAspect) const
219 {
220   switch (theAspect)
221   {
222     case Graphic3d_ASPECT_LINE:      return !LineAspect().IsNull();
223     case Graphic3d_ASPECT_TEXT:      return !TextAspect().IsNull();
224     case Graphic3d_ASPECT_MARKER:    return !MarkerAspect().IsNull();
225     case Graphic3d_ASPECT_FILL_AREA: return !FillAreaAspect().IsNull();
226     default:                         return Standard_False;
227   }
228 }
229
230 // =======================================================================
231 // function : GroupPrimitivesAspect
232 // purpose  :
233 // =======================================================================
234 void Graphic3d_Group::GroupPrimitivesAspect (const Handle(Graphic3d_AspectLine3d)&     theAspLine,
235                                              const Handle(Graphic3d_AspectText3d)&     theAspText,
236                                              const Handle(Graphic3d_AspectMarker3d)&   theAspMarker,
237                                              const Handle(Graphic3d_AspectFillArea3d)& theAspFill) const
238 {
239   if (!theAspLine.IsNull())
240   {
241     Handle(Graphic3d_AspectLine3d) aLineAspect = LineAspect();
242     if (!aLineAspect.IsNull())
243     {
244       *theAspLine.operator->() = *aLineAspect;
245     }
246   }
247
248   if (!theAspText.IsNull())
249   {
250     Handle(Graphic3d_AspectText3d) aTextAspect = TextAspect();
251     if (!aTextAspect.IsNull())
252     {
253       *theAspText.operator->() = *aTextAspect;
254     }
255   }
256
257   if (!theAspMarker.IsNull())
258   {
259     Handle(Graphic3d_AspectMarker3d) aMarkerAspect = MarkerAspect();
260     if (!aMarkerAspect.IsNull())
261     {
262       *theAspMarker.operator->() = *aMarkerAspect;
263     }
264   }
265
266   if (!theAspFill.IsNull())
267   {
268     Handle(Graphic3d_AspectFillArea3d) aFillAspect = FillAreaAspect();
269     if (!aFillAspect.IsNull())
270     {
271       *theAspFill.operator->() = *aFillAspect;
272     }
273   }
274 }
275
276 // =======================================================================
277 // function : AddPrimitiveArray
278 // purpose  :
279 // =======================================================================
280 void Graphic3d_Group::AddPrimitiveArray (const Handle(Graphic3d_ArrayOfPrimitives)& thePrim,
281                                          const Standard_Boolean                     theToEvalMinMax)
282 {
283   if (IsDeleted()
284   || !thePrim->IsValid())
285   {
286     return;
287   }
288
289   AddPrimitiveArray (thePrim->Type(), thePrim->Indices(), thePrim->Attributes(), thePrim->Bounds(), theToEvalMinMax);
290 }
291
292 // =======================================================================
293 // function : AddPrimitiveArray
294 // purpose  :
295 // =======================================================================
296 void Graphic3d_Group::AddPrimitiveArray (const Graphic3d_TypeOfPrimitiveArray theType,
297                                          const Handle(Graphic3d_IndexBuffer)& ,
298                                          const Handle(Graphic3d_Buffer)&      theAttribs,
299                                          const Handle(Graphic3d_BoundBuffer)& ,
300                                          const Standard_Boolean               theToEvalMinMax)
301 {
302   if (IsDeleted()
303    || theAttribs.IsNull())
304   {
305     return;
306   }
307
308   if (!myContainsFacet
309     && theType != Graphic3d_TOPA_POLYLINES
310     && theType != Graphic3d_TOPA_SEGMENTS
311     && theType != Graphic3d_TOPA_POINTS)
312   {
313     myStructure->GroupsWithFacet (1);
314     myContainsFacet = true;
315   }
316
317   if (theToEvalMinMax)
318   {
319     const Standard_Integer aNbVerts = theAttribs->NbElements;
320     for (Standard_Integer anAttribIter = 0; anAttribIter < theAttribs->NbAttributes; ++anAttribIter)
321     {
322       const Graphic3d_Attribute& anAttrib = theAttribs->Attribute (anAttribIter);
323       if (anAttrib.Id != Graphic3d_TOA_POS)
324       {
325         continue;
326       }
327
328       const size_t anOffset = theAttribs->AttributeOffset (anAttribIter);
329       switch (anAttrib.DataType)
330       {
331         case Graphic3d_TOD_VEC2:
332         {
333           for (Standard_Integer aVertIter = 0; aVertIter < aNbVerts; ++aVertIter)
334           {
335             const Graphic3d_Vec2& aVert = *reinterpret_cast<const Graphic3d_Vec2* >(theAttribs->value (aVertIter) + anOffset);
336             myBounds.Add (Graphic3d_Vec4 (aVert.x(), aVert.y(), 0.0f, 1.0f));
337           }
338           break;
339         }
340         case Graphic3d_TOD_VEC3:
341         case Graphic3d_TOD_VEC4:
342         {
343           for (Standard_Integer aVertIter = 0; aVertIter < aNbVerts; ++aVertIter)
344           {
345             const Graphic3d_Vec3& aVert = *reinterpret_cast<const Graphic3d_Vec3* >(theAttribs->value (aVertIter) + anOffset);
346             myBounds.Add (Graphic3d_Vec4 (aVert.x(), aVert.y(), aVert.z(), 1.0f));
347           }
348           break;
349         }
350         default: break;
351       }
352       break;
353     }
354   }
355
356   Update();
357 }
358
359 // =======================================================================
360 // function : Marker
361 // purpose  :
362 // =======================================================================
363 void Graphic3d_Group::Marker (const Graphic3d_Vertex& thePoint,
364                               const Standard_Boolean  theToEvalMinMax)
365 {
366   Handle(Graphic3d_ArrayOfPoints) aPoints = new Graphic3d_ArrayOfPoints (1);
367   aPoints->AddVertex (thePoint.X(), thePoint.Y(), thePoint.Z());
368   AddPrimitiveArray (aPoints, theToEvalMinMax);
369 }
370
371 // =======================================================================
372 // function : Text
373 // purpose  :
374 // =======================================================================
375 void Graphic3d_Group::Text (const Standard_CString                  /*theText*/,
376                             const Graphic3d_Vertex&                 thePoint,
377                             const Standard_Real                     /*theHeight*/,
378                             const Quantity_PlaneAngle               /*theAngle*/,
379                             const Graphic3d_TextPath                /*theTp*/,
380                             const Graphic3d_HorizontalTextAlignment /*theHta*/,
381                             const Graphic3d_VerticalTextAlignment   /*theVta*/,
382                             const Standard_Boolean                  theToEvalMinMax)
383 {
384   if (IsDeleted())
385   {
386     return;
387   }
388
389   if (theToEvalMinMax)
390   {
391     Standard_ShortReal x, y, z;
392     thePoint.Coord (x, y, z);
393     myStructure->CStructure()->Is2dText = Standard_True;
394     myBounds.Add (Graphic3d_Vec4 (static_cast<Standard_ShortReal> (x),
395                                   static_cast<Standard_ShortReal> (y),
396                                   static_cast<Standard_ShortReal> (z),
397                                   1.0f));
398   }
399   Update();
400 }
401
402 // =======================================================================
403 // function : Text
404 // purpose  :
405 // =======================================================================
406 void Graphic3d_Group::Text (const Standard_CString  theText,
407                             const Graphic3d_Vertex& thePoint,
408                             const Standard_Real     theHeight,
409                             const Standard_Boolean  theToEvalMinMax)
410 {
411   Text (theText, thePoint, theHeight, 0.0,
412         Graphic3d_TP_RIGHT, Graphic3d_HTA_LEFT, Graphic3d_VTA_BOTTOM, theToEvalMinMax);
413 }
414
415 // =======================================================================
416 // function : Text
417 // purpose  :
418 // =======================================================================
419 void Graphic3d_Group::Text (const TCollection_ExtendedString&       theText,
420                             const Graphic3d_Vertex&                 thePoint,
421                             const Standard_Real                     theHeight,
422                             const Quantity_PlaneAngle               theAngle,
423                             const Graphic3d_TextPath                theTp,
424                             const Graphic3d_HorizontalTextAlignment theHta,
425                             const Graphic3d_VerticalTextAlignment   theVta,
426                             const Standard_Boolean                  theToEvalMinMax)
427 {
428   const NCollection_String aText (theText.ToExtString());
429   Text (aText.ToCString(), thePoint, theHeight, theAngle,
430         theTp, theHta, theVta, theToEvalMinMax);
431 }
432
433 // =======================================================================
434 // function : Text
435 // purpose  :
436 // =======================================================================
437 void Graphic3d_Group::Text (const TCollection_ExtendedString&       theText,
438                             const gp_Ax2&                           theOrientation,
439                             const Standard_Real                     theHeight,
440                             const Quantity_PlaneAngle               theAngle,
441                             const Graphic3d_TextPath                theTP,
442                             const Graphic3d_HorizontalTextAlignment theHTA,
443                             const Graphic3d_VerticalTextAlignment   theVTA,
444                             const Standard_Boolean                  theToEvalMinMax,
445                             const Standard_Boolean                  theHasOwnAnchor)
446 {
447   const NCollection_String aText (theText.ToExtString());
448   Text (aText.ToCString(),
449         theOrientation,
450         theHeight,
451         theAngle,
452         theTP,
453         theHTA,
454         theVTA,
455         theToEvalMinMax,
456         theHasOwnAnchor);
457 }
458
459 // =======================================================================
460 // function : Text
461 // purpose  :
462 // =======================================================================
463 void Graphic3d_Group::Text (const Standard_CString                  /*theText*/,
464                             const gp_Ax2&                           theOrientation,
465                             const Standard_Real                     /*theHeight*/,
466                             const Quantity_PlaneAngle               /*theAngle*/,
467                             const Graphic3d_TextPath                /*theTp*/,
468                             const Graphic3d_HorizontalTextAlignment /*theHta*/,
469                             const Graphic3d_VerticalTextAlignment   /*theVta*/,
470                             const Standard_Boolean                  theToEvalMinMax,
471                             const Standard_Boolean                  /*theHasOwnAnchor*/)
472 {
473   if (IsDeleted())
474   {
475     return;
476   }
477
478   if (theToEvalMinMax)
479   {
480     myStructure->CStructure()->Is2dText = Standard_False;
481     myBounds.Add (Graphic3d_Vec4 (static_cast<Standard_ShortReal> (theOrientation.Location().X()),
482                                   static_cast<Standard_ShortReal> (theOrientation.Location().Y()),
483                                   static_cast<Standard_ShortReal> (theOrientation.Location().Z()),
484                                   1.0f));
485   }
486   Update();
487 }
488
489 // =======================================================================
490 // function : Text
491 // purpose  :
492 // =======================================================================
493 void Graphic3d_Group::Text (const TCollection_ExtendedString& theText,
494                             const Graphic3d_Vertex&           thePoint,
495                             const Standard_Real               theHeight,
496                             const Standard_Boolean            theToEvalMinMax)
497 {
498   const NCollection_String aText (theText.ToExtString());
499   Text (aText.ToCString(), thePoint, theHeight, 0.0,
500         Graphic3d_TP_RIGHT, Graphic3d_HTA_LEFT, Graphic3d_VTA_BOTTOM, theToEvalMinMax);
501 }