e85870d10c176c4a1b4ae71b07df0e6bff9e721a
[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,Standard_Transient)
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();
212 }
213
214 // =======================================================================
215 // function : AddPrimitiveArray
216 // purpose  :
217 // =======================================================================
218 void Graphic3d_Group::AddPrimitiveArray (const Handle(Graphic3d_ArrayOfPrimitives)& thePrim,
219                                          const Standard_Boolean                     theToEvalMinMax)
220 {
221   if (IsDeleted()
222   || !thePrim->IsValid())
223   {
224     return;
225   }
226
227   AddPrimitiveArray (thePrim->Type(), thePrim->Indices(), thePrim->Attributes(), thePrim->Bounds(), theToEvalMinMax);
228 }
229
230 // =======================================================================
231 // function : AddPrimitiveArray
232 // purpose  :
233 // =======================================================================
234 void Graphic3d_Group::AddPrimitiveArray (const Graphic3d_TypeOfPrimitiveArray theType,
235                                          const Handle(Graphic3d_IndexBuffer)& ,
236                                          const Handle(Graphic3d_Buffer)&      theAttribs,
237                                          const Handle(Graphic3d_BoundBuffer)& ,
238                                          const Standard_Boolean               theToEvalMinMax)
239 {
240   if (IsDeleted()
241    || theAttribs.IsNull())
242   {
243     return;
244   }
245
246   if (!myContainsFacet
247     && theType != Graphic3d_TOPA_POLYLINES
248     && theType != Graphic3d_TOPA_SEGMENTS
249     && theType != Graphic3d_TOPA_POINTS)
250   {
251     myStructure->GroupsWithFacet (1);
252     myContainsFacet = true;
253   }
254
255   if (!theToEvalMinMax)
256   {
257     Update();
258     return;
259   }
260
261   const Standard_Integer aNbVerts = theAttribs->NbElements;
262   Standard_Integer anAttribIndex = 0;
263   Standard_Size anAttribStride = 0;
264   const Standard_Byte* aDataPtr = theAttribs->AttributeData (Graphic3d_TOA_POS, anAttribIndex, anAttribStride);
265   if (aDataPtr == NULL)
266   {
267     Update();
268     return;
269   }
270
271   switch (theAttribs->Attribute (anAttribIndex).DataType)
272   {
273     case Graphic3d_TOD_VEC2:
274     {
275       for (Standard_Integer aVertIter = 0; aVertIter < aNbVerts; ++aVertIter)
276       {
277         const Graphic3d_Vec2& aVert = *reinterpret_cast<const Graphic3d_Vec2* >(aDataPtr + anAttribStride * aVertIter);
278         myBounds.Add (Graphic3d_Vec4 (aVert.x(), aVert.y(), 0.0f, 1.0f));
279       }
280       break;
281     }
282     case Graphic3d_TOD_VEC3:
283     case Graphic3d_TOD_VEC4:
284     {
285       for (Standard_Integer aVertIter = 0; aVertIter < aNbVerts; ++aVertIter)
286       {
287         const Graphic3d_Vec3& aVert = *reinterpret_cast<const Graphic3d_Vec3* >(aDataPtr + anAttribStride * aVertIter);
288         myBounds.Add (Graphic3d_Vec4 (aVert.x(), aVert.y(), aVert.z(), 1.0f));
289       }
290       break;
291     }
292     default: break;
293   }
294   Update();
295 }
296
297 // =======================================================================
298 // function : Marker
299 // purpose  :
300 // =======================================================================
301 void Graphic3d_Group::Marker (const Graphic3d_Vertex& thePoint,
302                               const Standard_Boolean  theToEvalMinMax)
303 {
304   Handle(Graphic3d_ArrayOfPoints) aPoints = new Graphic3d_ArrayOfPoints (1);
305   aPoints->AddVertex (thePoint.X(), thePoint.Y(), thePoint.Z());
306   AddPrimitiveArray (aPoints, theToEvalMinMax);
307 }
308
309 // =======================================================================
310 // function : Text
311 // purpose  :
312 // =======================================================================
313 void Graphic3d_Group::Text (const Standard_CString                  /*theText*/,
314                             const Graphic3d_Vertex&                 thePoint,
315                             const Standard_Real                     /*theHeight*/,
316                             const Standard_Real                     /*theAngle*/,
317                             const Graphic3d_TextPath                /*theTp*/,
318                             const Graphic3d_HorizontalTextAlignment /*theHta*/,
319                             const Graphic3d_VerticalTextAlignment   /*theVta*/,
320                             const Standard_Boolean                  theToEvalMinMax)
321 {
322   if (IsDeleted())
323   {
324     return;
325   }
326
327   if (theToEvalMinMax)
328   {
329     Standard_ShortReal x, y, z;
330     thePoint.Coord (x, y, z);
331     myStructure->CStructure()->Is2dText = Standard_True;
332     myBounds.Add (Graphic3d_Vec4 (static_cast<Standard_ShortReal> (x),
333                                   static_cast<Standard_ShortReal> (y),
334                                   static_cast<Standard_ShortReal> (z),
335                                   1.0f));
336   }
337   Update();
338 }
339
340 // =======================================================================
341 // function : Text
342 // purpose  :
343 // =======================================================================
344 void Graphic3d_Group::Text (const Standard_CString  theText,
345                             const Graphic3d_Vertex& thePoint,
346                             const Standard_Real     theHeight,
347                             const Standard_Boolean  theToEvalMinMax)
348 {
349   Text (theText, thePoint, theHeight, 0.0,
350         Graphic3d_TP_RIGHT, Graphic3d_HTA_LEFT, Graphic3d_VTA_BOTTOM, theToEvalMinMax);
351 }
352
353 // =======================================================================
354 // function : Text
355 // purpose  :
356 // =======================================================================
357 void Graphic3d_Group::Text (const TCollection_ExtendedString&       theText,
358                             const Graphic3d_Vertex&                 thePoint,
359                             const Standard_Real                     theHeight,
360                             const Standard_Real                     theAngle,
361                             const Graphic3d_TextPath                theTp,
362                             const Graphic3d_HorizontalTextAlignment theHta,
363                             const Graphic3d_VerticalTextAlignment   theVta,
364                             const Standard_Boolean                  theToEvalMinMax)
365 {
366   const NCollection_String aText (theText.ToExtString());
367   Text (aText.ToCString(), thePoint, theHeight, theAngle,
368         theTp, theHta, theVta, theToEvalMinMax);
369 }
370
371 // =======================================================================
372 // function : Text
373 // purpose  :
374 // =======================================================================
375 void Graphic3d_Group::Text (const TCollection_ExtendedString&       theText,
376                             const gp_Ax2&                           theOrientation,
377                             const Standard_Real                     theHeight,
378                             const Standard_Real                     theAngle,
379                             const Graphic3d_TextPath                theTP,
380                             const Graphic3d_HorizontalTextAlignment theHTA,
381                             const Graphic3d_VerticalTextAlignment   theVTA,
382                             const Standard_Boolean                  theToEvalMinMax,
383                             const Standard_Boolean                  theHasOwnAnchor)
384 {
385   const NCollection_String aText (theText.ToExtString());
386   Text (aText.ToCString(),
387         theOrientation,
388         theHeight,
389         theAngle,
390         theTP,
391         theHTA,
392         theVTA,
393         theToEvalMinMax,
394         theHasOwnAnchor);
395 }
396
397 // =======================================================================
398 // function : Text
399 // purpose  :
400 // =======================================================================
401 void Graphic3d_Group::Text (const Standard_CString                  /*theText*/,
402                             const gp_Ax2&                           theOrientation,
403                             const Standard_Real                     /*theHeight*/,
404                             const Standard_Real                     /*theAngle*/,
405                             const Graphic3d_TextPath                /*theTp*/,
406                             const Graphic3d_HorizontalTextAlignment /*theHta*/,
407                             const Graphic3d_VerticalTextAlignment   /*theVta*/,
408                             const Standard_Boolean                  theToEvalMinMax,
409                             const Standard_Boolean                  /*theHasOwnAnchor*/)
410 {
411   if (IsDeleted())
412   {
413     return;
414   }
415
416   if (theToEvalMinMax)
417   {
418     myStructure->CStructure()->Is2dText = Standard_False;
419     myBounds.Add (Graphic3d_Vec4 (static_cast<Standard_ShortReal> (theOrientation.Location().X()),
420                                   static_cast<Standard_ShortReal> (theOrientation.Location().Y()),
421                                   static_cast<Standard_ShortReal> (theOrientation.Location().Z()),
422                                   1.0f));
423   }
424   Update();
425 }
426
427 // =======================================================================
428 // function : Text
429 // purpose  :
430 // =======================================================================
431 void Graphic3d_Group::Text (const TCollection_ExtendedString& theText,
432                             const Graphic3d_Vertex&           thePoint,
433                             const Standard_Real               theHeight,
434                             const Standard_Boolean            theToEvalMinMax)
435 {
436   const NCollection_String aText (theText.ToExtString());
437   Text (aText.ToCString(), thePoint, theHeight, 0.0,
438         Graphic3d_TP_RIGHT, Graphic3d_HTA_LEFT, Graphic3d_VTA_BOTTOM, theToEvalMinMax);
439 }