0027919: Visualization - support multiple transformation persistence groups within...
[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 : SetTransformPersistence
145 // purpose  :
146 // =======================================================================
147 void Graphic3d_Group::SetTransformPersistence (const Handle(Graphic3d_TransformPers)& theTrsfPers)
148 {
149   if (myTrsfPers != theTrsfPers)
150   {
151     myTrsfPers = theTrsfPers;
152     if (!IsDeleted()
153      && !theTrsfPers.IsNull())
154     {
155       myStructure->CStructure()->SetGroupTransformPersistence (true);
156     }
157   }
158 }
159
160 // =======================================================================
161 // function : SetMinMaxValues
162 // purpose  :
163 // =======================================================================
164 void Graphic3d_Group::SetMinMaxValues (const Standard_Real theXMin, const Standard_Real theYMin, const Standard_Real theZMin,
165                                        const Standard_Real theXMax, const Standard_Real theYMax, const Standard_Real theZMax)
166 {
167   myBounds = Graphic3d_BndBox4f (Graphic3d_Vec4 (static_cast<Standard_ShortReal> (theXMin),
168                                                  static_cast<Standard_ShortReal> (theYMin),
169                                                  static_cast<Standard_ShortReal> (theZMin),
170                                                  1.0f),
171                                  Graphic3d_Vec4 (static_cast<Standard_ShortReal> (theXMax),
172                                                  static_cast<Standard_ShortReal> (theYMax),
173                                                  static_cast<Standard_ShortReal> (theZMax),
174                                                  1.0f));
175 }
176
177 // =======================================================================
178 // function : Structure
179 // purpose  :
180 // =======================================================================
181 Handle(Graphic3d_Structure) Graphic3d_Group::Structure() const
182 {
183   return myStructure;
184 }
185
186 // =======================================================================
187 // function : MinMaxValues
188 // purpose  :
189 // =======================================================================
190 void Graphic3d_Group::MinMaxValues (Standard_Real& theXMin, Standard_Real& theYMin, Standard_Real& theZMin,
191                                     Standard_Real& theXMax, Standard_Real& theYMax, Standard_Real& theZMax) const
192 {
193   if (IsEmpty())
194   {
195     // Empty Group
196     theXMin = theYMin = theZMin = ShortRealFirst();
197     theXMax = theYMax = theZMax = ShortRealLast();
198   }
199   else if (myBounds.IsValid())
200   {
201     const Graphic3d_Vec4& aMinPt = myBounds.CornerMin();
202     const Graphic3d_Vec4& aMaxPt = myBounds.CornerMax();
203     theXMin = Standard_Real (aMinPt.x());
204     theYMin = Standard_Real (aMinPt.y());
205     theZMin = Standard_Real (aMinPt.z());
206     theXMax = Standard_Real (aMaxPt.x());
207     theYMax = Standard_Real (aMaxPt.y());
208     theZMax = Standard_Real (aMaxPt.z());
209   }
210   else
211   {
212     // for consistency with old API
213     theXMin = theYMin = theZMin = ShortRealLast();
214     theXMax = theYMax = theZMax = ShortRealFirst();
215   }
216 }
217
218 // =======================================================================
219 // function : Update
220 // purpose  :
221 // =======================================================================
222 void Graphic3d_Group::Update() const
223 {
224   if (IsDeleted())
225   {
226     return;
227   }
228
229   myStructure->StructureManager()->Update();
230 }
231
232 // =======================================================================
233 // function : AddPrimitiveArray
234 // purpose  :
235 // =======================================================================
236 void Graphic3d_Group::AddPrimitiveArray (const Handle(Graphic3d_ArrayOfPrimitives)& thePrim,
237                                          const Standard_Boolean                     theToEvalMinMax)
238 {
239   if (IsDeleted()
240   || !thePrim->IsValid())
241   {
242     return;
243   }
244
245   AddPrimitiveArray (thePrim->Type(), thePrim->Indices(), thePrim->Attributes(), thePrim->Bounds(), theToEvalMinMax);
246 }
247
248 // =======================================================================
249 // function : AddPrimitiveArray
250 // purpose  :
251 // =======================================================================
252 void Graphic3d_Group::AddPrimitiveArray (const Graphic3d_TypeOfPrimitiveArray theType,
253                                          const Handle(Graphic3d_IndexBuffer)& ,
254                                          const Handle(Graphic3d_Buffer)&      theAttribs,
255                                          const Handle(Graphic3d_BoundBuffer)& ,
256                                          const Standard_Boolean               theToEvalMinMax)
257 {
258   if (IsDeleted()
259    || theAttribs.IsNull())
260   {
261     return;
262   }
263
264   if (!myContainsFacet
265     && theType != Graphic3d_TOPA_POLYLINES
266     && theType != Graphic3d_TOPA_SEGMENTS
267     && theType != Graphic3d_TOPA_POINTS)
268   {
269     myStructure->GroupsWithFacet (1);
270     myContainsFacet = true;
271   }
272
273   if (!theToEvalMinMax)
274   {
275     Update();
276     return;
277   }
278
279   const Standard_Integer aNbVerts = theAttribs->NbElements;
280   Standard_Integer anAttribIndex = 0;
281   Standard_Size anAttribStride = 0;
282   const Standard_Byte* aDataPtr = theAttribs->AttributeData (Graphic3d_TOA_POS, anAttribIndex, anAttribStride);
283   if (aDataPtr == NULL)
284   {
285     Update();
286     return;
287   }
288
289   switch (theAttribs->Attribute (anAttribIndex).DataType)
290   {
291     case Graphic3d_TOD_VEC2:
292     {
293       for (Standard_Integer aVertIter = 0; aVertIter < aNbVerts; ++aVertIter)
294       {
295         const Graphic3d_Vec2& aVert = *reinterpret_cast<const Graphic3d_Vec2* >(aDataPtr + anAttribStride * aVertIter);
296         myBounds.Add (Graphic3d_Vec4 (aVert.x(), aVert.y(), 0.0f, 1.0f));
297       }
298       break;
299     }
300     case Graphic3d_TOD_VEC3:
301     case Graphic3d_TOD_VEC4:
302     {
303       for (Standard_Integer aVertIter = 0; aVertIter < aNbVerts; ++aVertIter)
304       {
305         const Graphic3d_Vec3& aVert = *reinterpret_cast<const Graphic3d_Vec3* >(aDataPtr + anAttribStride * aVertIter);
306         myBounds.Add (Graphic3d_Vec4 (aVert.x(), aVert.y(), aVert.z(), 1.0f));
307       }
308       break;
309     }
310     default: break;
311   }
312   Update();
313 }
314
315 // =======================================================================
316 // function : Marker
317 // purpose  :
318 // =======================================================================
319 void Graphic3d_Group::Marker (const Graphic3d_Vertex& thePoint,
320                               const Standard_Boolean  theToEvalMinMax)
321 {
322   Handle(Graphic3d_ArrayOfPoints) aPoints = new Graphic3d_ArrayOfPoints (1);
323   aPoints->AddVertex (thePoint.X(), thePoint.Y(), thePoint.Z());
324   AddPrimitiveArray (aPoints, theToEvalMinMax);
325 }
326
327 // =======================================================================
328 // function : Text
329 // purpose  :
330 // =======================================================================
331 void Graphic3d_Group::Text (const Standard_CString                  theText,
332                             const Graphic3d_Vertex&                 thePoint,
333                             const Standard_Real                     theHeight,
334                             const Standard_Real                     /*theAngle*/,
335                             const Graphic3d_TextPath                /*theTp*/,
336                             const Graphic3d_HorizontalTextAlignment theHta,
337                             const Graphic3d_VerticalTextAlignment   theVta,
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   aText->SetHorizontalAlignment (theHta);
344   aText->SetVerticalAlignment (theVta);
345   AddText (aText, theToEvalMinMax);
346 }
347
348 // =======================================================================
349 // function : Text
350 // purpose  :
351 // =======================================================================
352 void Graphic3d_Group::Text (const Standard_CString  theText,
353                             const Graphic3d_Vertex& thePoint,
354                             const Standard_Real     theHeight,
355                             const Standard_Boolean  theToEvalMinMax)
356 {
357   Handle(Graphic3d_Text) aText = new Graphic3d_Text ((Standard_ShortReal)theHeight);
358   aText->SetText (theText);
359   aText->SetPosition (gp_Pnt (thePoint.X(), thePoint.Y(), thePoint.Z()));
360   AddText (aText, theToEvalMinMax);
361 }
362
363 // =======================================================================
364 // function : Text
365 // purpose  :
366 // =======================================================================
367 void Graphic3d_Group::Text (const TCollection_ExtendedString&       theText,
368                             const Graphic3d_Vertex&                 thePoint,
369                             const Standard_Real                     theHeight,
370                             const Standard_Real                     /*theAngle*/,
371                             const Graphic3d_TextPath                /*theTp*/,
372                             const Graphic3d_HorizontalTextAlignment theHta,
373                             const Graphic3d_VerticalTextAlignment   theVta,
374                             const Standard_Boolean                  theToEvalMinMax)
375 {
376   Handle(Graphic3d_Text) aText = new Graphic3d_Text ((Standard_ShortReal)theHeight);
377   aText->SetText (theText.ToExtString());
378   aText->SetPosition (gp_Pnt (thePoint.X(), thePoint.Y(), thePoint.Z()));
379   aText->SetHorizontalAlignment (theHta);
380   aText->SetVerticalAlignment (theVta);
381   AddText (aText, theToEvalMinMax);
382 }
383
384 // =======================================================================
385 // function : Text
386 // purpose  :
387 // =======================================================================
388 void Graphic3d_Group::Text (const TCollection_ExtendedString&       theText,
389                             const gp_Ax2&                           theOrientation,
390                             const Standard_Real                     theHeight,
391                             const Standard_Real                     /*theAngle*/,
392                             const Graphic3d_TextPath                /*theTP*/,
393                             const Graphic3d_HorizontalTextAlignment theHta,
394                             const Graphic3d_VerticalTextAlignment   theVta,
395                             const Standard_Boolean                  theToEvalMinMax,
396                             const Standard_Boolean                  theHasOwnAnchor)
397 {
398   Handle(Graphic3d_Text) aText = new Graphic3d_Text ((Standard_ShortReal)theHeight);
399   aText->SetText (theText.ToExtString());
400   aText->SetOrientation (theOrientation);
401   aText->SetOwnAnchorPoint (theHasOwnAnchor);
402   aText->SetHorizontalAlignment (theHta);
403   aText->SetVerticalAlignment (theVta);
404   AddText (aText, theToEvalMinMax);
405 }
406
407 // =======================================================================
408 // function : Text
409 // purpose  :
410 // =======================================================================
411 void Graphic3d_Group::Text (const Standard_CString                  theText,
412                             const gp_Ax2&                           theOrientation,
413                             const Standard_Real                     theHeight,
414                             const Standard_Real                     /*theAngle*/,
415                             const Graphic3d_TextPath                /*theTp*/,
416                             const Graphic3d_HorizontalTextAlignment theHta,
417                             const Graphic3d_VerticalTextAlignment   theVta,
418                             const Standard_Boolean                  theToEvalMinMax,
419                             const Standard_Boolean                  theHasOwnAnchor)
420 {
421   Handle(Graphic3d_Text) aText = new Graphic3d_Text ((Standard_ShortReal)theHeight);
422   aText->SetText (theText);
423   aText->SetOrientation (theOrientation);
424   aText->SetOwnAnchorPoint (theHasOwnAnchor);
425   aText->SetHorizontalAlignment (theHta);
426   aText->SetVerticalAlignment (theVta);
427   AddText (aText, theToEvalMinMax);
428 }
429
430 // =======================================================================
431 // function : Text
432 // purpose  :
433 // =======================================================================
434 void Graphic3d_Group::Text (const TCollection_ExtendedString& theText,
435                             const Graphic3d_Vertex&           thePoint,
436                             const Standard_Real               theHeight,
437                             const Standard_Boolean            theToEvalMinMax)
438 {
439   Handle(Graphic3d_Text) aText = new Graphic3d_Text ((Standard_ShortReal)theHeight);
440   aText->SetText (theText.ToExtString());
441   aText->SetPosition (gp_Pnt (thePoint.X(), thePoint.Y(), thePoint.Z()));
442   AddText (aText, theToEvalMinMax);
443 }
444
445 // =======================================================================
446 // function : AddText
447 // purpose  :
448 // =======================================================================
449 void Graphic3d_Group::AddText (const Handle(Graphic3d_Text)& theTextParams,
450                                const Standard_Boolean theToEvalMinMax)
451 {
452   if (IsDeleted())
453   {
454     return;
455   }
456
457   if (theToEvalMinMax)
458   {
459     myStructure->CStructure()->Is2dText = !theTextParams->HasPlane();
460
461     gp_Pnt aPosition = theTextParams->Position();
462     myBounds.Add (Graphic3d_Vec4 ((Standard_ShortReal)aPosition.X(), (Standard_ShortReal)aPosition.Y(), (Standard_ShortReal)aPosition.Z(), 1.0f));
463   }
464
465   Update();
466 }
467
468 // =======================================================================
469 // function : DumpJson
470 // purpose  :
471 // =======================================================================
472 void Graphic3d_Group::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
473 {
474   OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
475
476   OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, this)
477
478   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, myTrsfPers.get())
479
480   OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, myStructure)
481   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myBounds)
482
483   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsClosed)
484   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myContainsFacet)
485 }