0031431: Visualization, PrsMgr_PresentableObject - simplify HLR computing interface
[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_Text.hxx>
33 #include <Graphic3d_TextureMap.hxx>
34 #include <Graphic3d_TransModeFlags.hxx>
35 #include <Message.hxx>
36 #include <Message_Messenger.hxx>
37 #include <NCollection_String.hxx>
38 #include <Standard_OutOfRange.hxx>
39 #include <Standard_Type.hxx>
40 #include <TCollection_AsciiString.hxx>
41 #include <TCollection_ExtendedString.hxx>
42
43 IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_Group,Standard_Transient)
44
45 // =======================================================================
46 // function : Graphic3d_Group
47 // purpose  :
48 // =======================================================================
49 Graphic3d_Group::Graphic3d_Group (const Handle(Graphic3d_Structure)& theStruct)
50 : myStructure     (theStruct.operator->()),
51   myIsClosed      (false),
52   myContainsFacet (false)
53 {
54   //
55 }
56
57 // =======================================================================
58 // function : ~Graphic3d_Group
59 // purpose  :
60 // =======================================================================
61 Graphic3d_Group::~Graphic3d_Group()
62 {
63   // tell graphics driver to clear internal resources of the group
64   Clear (Standard_False);
65 }
66
67 // =======================================================================
68 // function : Clear
69 // purpose  :
70 // =======================================================================
71 void Graphic3d_Group::Clear (Standard_Boolean theUpdateStructureMgr)
72 {
73   if (IsDeleted())
74   {
75     return;
76   }
77
78   myBounds.Clear();
79
80   if (myContainsFacet)
81   {
82     myStructure->GroupsWithFacet (-1);
83     myContainsFacet = false;
84   }
85
86   // clear method could be used on Graphic3d_Structure destruction,
87   // and its structure manager could be already destroyed, in that
88   // case we don't need to update it;
89   if (theUpdateStructureMgr)
90   {
91     Update();
92   }
93 }
94
95 // =======================================================================
96 // function : Remove
97 // purpose  :
98 // =======================================================================
99 void Graphic3d_Group::Remove()
100 {
101   if (IsDeleted())
102   {
103     return;
104   }
105
106   if (myContainsFacet)
107   {
108     myStructure->GroupsWithFacet (-1);
109     myContainsFacet = false;
110   }
111   myStructure->Remove (this);
112
113   Update();
114
115   myBounds.Clear();
116 }
117
118 // =======================================================================
119 // function : IsDeleted
120 // purpose  :
121 // =======================================================================
122 Standard_Boolean Graphic3d_Group::IsDeleted() const
123 {
124   return myStructure == NULL
125       || myStructure->IsDeleted();
126 }
127
128 // =======================================================================
129 // function : IsEmpty
130 // purpose  :
131 // =======================================================================
132 Standard_Boolean Graphic3d_Group::IsEmpty() const
133 {
134   if (IsDeleted())
135   {
136     return Standard_True;
137   }
138
139   return !myStructure->IsInfinite()
140       && !myBounds.IsValid();
141 }
142
143 // =======================================================================
144 // function : SetMinMaxValues
145 // purpose  :
146 // =======================================================================
147 void Graphic3d_Group::SetMinMaxValues (const Standard_Real theXMin, const Standard_Real theYMin, const Standard_Real theZMin,
148                                        const Standard_Real theXMax, const Standard_Real theYMax, const Standard_Real theZMax)
149 {
150   myBounds = Graphic3d_BndBox4f (Graphic3d_Vec4 (static_cast<Standard_ShortReal> (theXMin),
151                                                  static_cast<Standard_ShortReal> (theYMin),
152                                                  static_cast<Standard_ShortReal> (theZMin),
153                                                  1.0f),
154                                  Graphic3d_Vec4 (static_cast<Standard_ShortReal> (theXMax),
155                                                  static_cast<Standard_ShortReal> (theYMax),
156                                                  static_cast<Standard_ShortReal> (theZMax),
157                                                  1.0f));
158 }
159
160 // =======================================================================
161 // function : Structure
162 // purpose  :
163 // =======================================================================
164 Handle(Graphic3d_Structure) Graphic3d_Group::Structure() const
165 {
166   return myStructure;
167 }
168
169 // =======================================================================
170 // function : MinMaxValues
171 // purpose  :
172 // =======================================================================
173 void Graphic3d_Group::MinMaxValues (Standard_Real& theXMin, Standard_Real& theYMin, Standard_Real& theZMin,
174                                     Standard_Real& theXMax, Standard_Real& theYMax, Standard_Real& theZMax) const
175 {
176   if (IsEmpty())
177   {
178     // Empty Group
179     theXMin = theYMin = theZMin = ShortRealFirst();
180     theXMax = theYMax = theZMax = ShortRealLast();
181   }
182   else if (myBounds.IsValid())
183   {
184     const Graphic3d_Vec4& aMinPt = myBounds.CornerMin();
185     const Graphic3d_Vec4& aMaxPt = myBounds.CornerMax();
186     theXMin = Standard_Real (aMinPt.x());
187     theYMin = Standard_Real (aMinPt.y());
188     theZMin = Standard_Real (aMinPt.z());
189     theXMax = Standard_Real (aMaxPt.x());
190     theYMax = Standard_Real (aMaxPt.y());
191     theZMax = Standard_Real (aMaxPt.z());
192   }
193   else
194   {
195     // for consistency with old API
196     theXMin = theYMin = theZMin = ShortRealLast();
197     theXMax = theYMax = theZMax = ShortRealFirst();
198   }
199 }
200
201 // =======================================================================
202 // function : Update
203 // purpose  :
204 // =======================================================================
205 void Graphic3d_Group::Update() const
206 {
207   if (IsDeleted())
208   {
209     return;
210   }
211
212   myStructure->StructureManager()->Update();
213 }
214
215 // =======================================================================
216 // function : AddPrimitiveArray
217 // purpose  :
218 // =======================================================================
219 void Graphic3d_Group::AddPrimitiveArray (const Handle(Graphic3d_ArrayOfPrimitives)& thePrim,
220                                          const Standard_Boolean                     theToEvalMinMax)
221 {
222   if (IsDeleted()
223   || !thePrim->IsValid())
224   {
225     return;
226   }
227
228   AddPrimitiveArray (thePrim->Type(), thePrim->Indices(), thePrim->Attributes(), thePrim->Bounds(), theToEvalMinMax);
229 }
230
231 // =======================================================================
232 // function : AddPrimitiveArray
233 // purpose  :
234 // =======================================================================
235 void Graphic3d_Group::AddPrimitiveArray (const Graphic3d_TypeOfPrimitiveArray theType,
236                                          const Handle(Graphic3d_IndexBuffer)& ,
237                                          const Handle(Graphic3d_Buffer)&      theAttribs,
238                                          const Handle(Graphic3d_BoundBuffer)& ,
239                                          const Standard_Boolean               theToEvalMinMax)
240 {
241   if (IsDeleted()
242    || theAttribs.IsNull())
243   {
244     return;
245   }
246
247   if (!myContainsFacet
248     && theType != Graphic3d_TOPA_POLYLINES
249     && theType != Graphic3d_TOPA_SEGMENTS
250     && theType != Graphic3d_TOPA_POINTS)
251   {
252     myStructure->GroupsWithFacet (1);
253     myContainsFacet = true;
254   }
255
256   if (!theToEvalMinMax)
257   {
258     Update();
259     return;
260   }
261
262   const Standard_Integer aNbVerts = theAttribs->NbElements;
263   Standard_Integer anAttribIndex = 0;
264   Standard_Size anAttribStride = 0;
265   const Standard_Byte* aDataPtr = theAttribs->AttributeData (Graphic3d_TOA_POS, anAttribIndex, anAttribStride);
266   if (aDataPtr == NULL)
267   {
268     Update();
269     return;
270   }
271
272   switch (theAttribs->Attribute (anAttribIndex).DataType)
273   {
274     case Graphic3d_TOD_VEC2:
275     {
276       for (Standard_Integer aVertIter = 0; aVertIter < aNbVerts; ++aVertIter)
277       {
278         const Graphic3d_Vec2& aVert = *reinterpret_cast<const Graphic3d_Vec2* >(aDataPtr + anAttribStride * aVertIter);
279         myBounds.Add (Graphic3d_Vec4 (aVert.x(), aVert.y(), 0.0f, 1.0f));
280       }
281       break;
282     }
283     case Graphic3d_TOD_VEC3:
284     case Graphic3d_TOD_VEC4:
285     {
286       for (Standard_Integer aVertIter = 0; aVertIter < aNbVerts; ++aVertIter)
287       {
288         const Graphic3d_Vec3& aVert = *reinterpret_cast<const Graphic3d_Vec3* >(aDataPtr + anAttribStride * aVertIter);
289         myBounds.Add (Graphic3d_Vec4 (aVert.x(), aVert.y(), aVert.z(), 1.0f));
290       }
291       break;
292     }
293     default: break;
294   }
295   Update();
296 }
297
298 // =======================================================================
299 // function : Marker
300 // purpose  :
301 // =======================================================================
302 void Graphic3d_Group::Marker (const Graphic3d_Vertex& thePoint,
303                               const Standard_Boolean  theToEvalMinMax)
304 {
305   Handle(Graphic3d_ArrayOfPoints) aPoints = new Graphic3d_ArrayOfPoints (1);
306   aPoints->AddVertex (thePoint.X(), thePoint.Y(), thePoint.Z());
307   AddPrimitiveArray (aPoints, theToEvalMinMax);
308 }
309
310 // =======================================================================
311 // function : Text
312 // purpose  :
313 // =======================================================================
314 void Graphic3d_Group::Text (const Standard_CString                  theText,
315                             const Graphic3d_Vertex&                 thePoint,
316                             const Standard_Real                     theHeight,
317                             const Standard_Real                     /*theAngle*/,
318                             const Graphic3d_TextPath                /*theTp*/,
319                             const Graphic3d_HorizontalTextAlignment theHta,
320                             const Graphic3d_VerticalTextAlignment   theVta,
321                             const Standard_Boolean                  theToEvalMinMax)
322 {
323   Handle(Graphic3d_Text) aText = new Graphic3d_Text ((Standard_ShortReal)theHeight);
324   aText->SetText (theText);
325   aText->SetPosition (gp_Pnt (thePoint.X(), thePoint.Y(), thePoint.Z()));
326   aText->SetHorizontalAlignment (theHta);
327   aText->SetVerticalAlignment (theVta);
328   AddText (aText, theToEvalMinMax);
329 }
330
331 // =======================================================================
332 // function : Text
333 // purpose  :
334 // =======================================================================
335 void Graphic3d_Group::Text (const Standard_CString  theText,
336                             const Graphic3d_Vertex& thePoint,
337                             const Standard_Real     theHeight,
338                             const Standard_Boolean  theToEvalMinMax)
339 {
340   Handle(Graphic3d_Text) aText = new Graphic3d_Text ((Standard_ShortReal)theHeight);
341   aText->SetText (theText);
342   aText->SetPosition (gp_Pnt (thePoint.X(), thePoint.Y(), thePoint.Z()));
343   AddText (aText, theToEvalMinMax);
344 }
345
346 // =======================================================================
347 // function : Text
348 // purpose  :
349 // =======================================================================
350 void Graphic3d_Group::Text (const TCollection_ExtendedString&       theText,
351                             const Graphic3d_Vertex&                 thePoint,
352                             const Standard_Real                     theHeight,
353                             const Standard_Real                     /*theAngle*/,
354                             const Graphic3d_TextPath                /*theTp*/,
355                             const Graphic3d_HorizontalTextAlignment theHta,
356                             const Graphic3d_VerticalTextAlignment   theVta,
357                             const Standard_Boolean                  theToEvalMinMax)
358 {
359   Handle(Graphic3d_Text) aText = new Graphic3d_Text ((Standard_ShortReal)theHeight);
360   aText->SetText (theText.ToExtString());
361   aText->SetPosition (gp_Pnt (thePoint.X(), thePoint.Y(), thePoint.Z()));
362   aText->SetHorizontalAlignment (theHta);
363   aText->SetVerticalAlignment (theVta);
364   AddText (aText, theToEvalMinMax);
365 }
366
367 // =======================================================================
368 // function : Text
369 // purpose  :
370 // =======================================================================
371 void Graphic3d_Group::Text (const TCollection_ExtendedString&       theText,
372                             const gp_Ax2&                           theOrientation,
373                             const Standard_Real                     theHeight,
374                             const Standard_Real                     /*theAngle*/,
375                             const Graphic3d_TextPath                /*theTP*/,
376                             const Graphic3d_HorizontalTextAlignment theHta,
377                             const Graphic3d_VerticalTextAlignment   theVta,
378                             const Standard_Boolean                  theToEvalMinMax,
379                             const Standard_Boolean                  theHasOwnAnchor)
380 {
381   Handle(Graphic3d_Text) aText = new Graphic3d_Text ((Standard_ShortReal)theHeight);
382   aText->SetText (theText.ToExtString());
383   aText->SetOrientation (theOrientation);
384   aText->SetOwnAnchorPoint (theHasOwnAnchor);
385   aText->SetHorizontalAlignment (theHta);
386   aText->SetVerticalAlignment (theVta);
387   AddText (aText, theToEvalMinMax);
388 }
389
390 // =======================================================================
391 // function : Text
392 // purpose  :
393 // =======================================================================
394 void Graphic3d_Group::Text (const Standard_CString                  theText,
395                             const gp_Ax2&                           theOrientation,
396                             const Standard_Real                     theHeight,
397                             const Standard_Real                     /*theAngle*/,
398                             const Graphic3d_TextPath                /*theTp*/,
399                             const Graphic3d_HorizontalTextAlignment theHta,
400                             const Graphic3d_VerticalTextAlignment   theVta,
401                             const Standard_Boolean                  theToEvalMinMax,
402                             const Standard_Boolean                  theHasOwnAnchor)
403 {
404   Handle(Graphic3d_Text) aText = new Graphic3d_Text ((Standard_ShortReal)theHeight);
405   aText->SetText (theText);
406   aText->SetOrientation (theOrientation);
407   aText->SetOwnAnchorPoint (theHasOwnAnchor);
408   aText->SetHorizontalAlignment (theHta);
409   aText->SetVerticalAlignment (theVta);
410   AddText (aText, theToEvalMinMax);
411 }
412
413 // =======================================================================
414 // function : Text
415 // purpose  :
416 // =======================================================================
417 void Graphic3d_Group::Text (const TCollection_ExtendedString& theText,
418                             const Graphic3d_Vertex&           thePoint,
419                             const Standard_Real               theHeight,
420                             const Standard_Boolean            theToEvalMinMax)
421 {
422   Handle(Graphic3d_Text) aText = new Graphic3d_Text ((Standard_ShortReal)theHeight);
423   aText->SetText (theText.ToExtString());
424   aText->SetPosition (gp_Pnt (thePoint.X(), thePoint.Y(), thePoint.Z()));
425   AddText (aText, theToEvalMinMax);
426 }
427
428 // =======================================================================
429 // function : AddText
430 // purpose  :
431 // =======================================================================
432 void Graphic3d_Group::AddText (const Handle(Graphic3d_Text)& theTextParams,
433                                const Standard_Boolean theToEvalMinMax)
434 {
435   if (IsDeleted())
436   {
437     return;
438   }
439
440   if (theToEvalMinMax)
441   {
442     myStructure->CStructure()->Is2dText = !theTextParams->HasPlane();
443
444     gp_Pnt aPosition = theTextParams->Position();
445     myBounds.Add (Graphic3d_Vec4 ((Standard_ShortReal)aPosition.X(), (Standard_ShortReal)aPosition.Y(), (Standard_ShortReal)aPosition.Z(), 1.0f));
446   }
447
448   Update();
449 }
450
451 // =======================================================================
452 // function : DumpJson
453 // purpose  :
454 // =======================================================================
455 void Graphic3d_Group::DumpJson (Standard_OStream& theOStream, Standard_Integer) const
456 {
457   OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
458
459   OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, this)
460   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsClosed)
461   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myContainsFacet)
462 }