0026885: Visualization - drop redundant aspects from structure level
[occt.git] / src / Graphic3d / Graphic3d_Group.cxx
index 24879de..c4d99e1 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#include <Graphic3d_Group.ixx>
 
+#include <gp_Ax2.hxx>
 #include <gp_Pnt.hxx>
 #include <Graphic3d_ArrayOfPoints.hxx>
-#include <Graphic3d_StructureManager.hxx>
+#include <Graphic3d_ArrayOfPrimitives.hxx>
+#include <Graphic3d_AspectFillArea3d.hxx>
+#include <Graphic3d_AspectLine3d.hxx>
+#include <Graphic3d_AspectMarker3d.hxx>
+#include <Graphic3d_AspectText3d.hxx>
+#include <Graphic3d_CStructure.hxx>
+#include <Graphic3d_Group.hxx>
+#include <Graphic3d_GroupDefinitionError.hxx>
 #include <Graphic3d_ShaderProgram.hxx>
-#include <Graphic3d_TransModeFlags.hxx>
+#include <Graphic3d_Structure.hxx>
+#include "Graphic3d_Structure.pxx"
+#include <Graphic3d_StructureManager.hxx>
 #include <Graphic3d_TextureMap.hxx>
+#include <Graphic3d_TransModeFlags.hxx>
 #include <Message.hxx>
 #include <Message_Messenger.hxx>
 #include <NCollection_String.hxx>
+#include <Standard_OutOfRange.hxx>
+#include <Standard_Type.hxx>
 #include <TCollection_AsciiString.hxx>
+#include <TCollection_ExtendedString.hxx>
 
-#include <Graphic3d_CStructure.hxx>
-#include <Graphic3d_Structure.pxx>
+IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_Group,MMgt_TShared)
 
-#define MyIsEmpty       myCBitFields.bool1
 #define MyContainsFacet myCBitFields.bool2
 
 // =======================================================================
 // purpose  :
 // =======================================================================
 Graphic3d_Group::Graphic3d_Group (const Handle(Graphic3d_Structure)& theStruct)
+: myIsClosed (Standard_False)
 {
-  myBounds.XMin  = ShortRealLast();
-  myBounds.YMin  = ShortRealLast();
-  myBounds.ZMin  = ShortRealLast();
-  myBounds.XMax  = ShortRealFirst();
-  myBounds.YMax  = ShortRealFirst();
-  myBounds.ZMax  = ShortRealFirst();
-
-  //
   // A small commentary on the usage of This!
   //
   // Graphic3d_Group is created in a structure. Graphic3d_Structure is a
@@ -59,8 +63,7 @@ Graphic3d_Group::Graphic3d_Group (const Handle(Graphic3d_Structure)& theStruct)
 
   myStructure = theStruct.operator->();
 
-  MyContainsFacet     = Standard_False,
-  MyIsEmpty           = Standard_True;
+  MyContainsFacet = Standard_False,
 
   ContextLine.IsDef     = 0;
   ContextText.IsDef     = 0;
@@ -94,19 +97,13 @@ void Graphic3d_Group::Clear (Standard_Boolean theUpdateStructureMgr)
   ContextMarker.IsDef   = 0,
   ContextFillArea.IsDef = 0;
 
-  myBounds.XMin = ShortRealLast();
-  myBounds.YMin = ShortRealLast();
-  myBounds.ZMin = ShortRealLast();
-  myBounds.XMax = ShortRealFirst();
-  myBounds.YMax = ShortRealFirst();
-  myBounds.ZMax = ShortRealFirst();
+  myBounds.Clear();
 
   if (MyContainsFacet)
   {
     myStructure->GroupsWithFacet (-1);
     MyContainsFacet = Standard_False;
   }
-  MyIsEmpty = Standard_True;
 
   // clear method could be used on Graphic3d_Structure destruction,
   // and its structure manager could be already destroyed, in that
@@ -147,14 +144,7 @@ void Graphic3d_Group::Remove()
 
   Update();
 
-  myBounds.XMin = ShortRealLast();
-  myBounds.YMin = ShortRealLast();
-  myBounds.ZMin = ShortRealLast();
-  myBounds.XMax = ShortRealFirst();
-  myBounds.YMax = ShortRealFirst();
-  myBounds.ZMax = ShortRealFirst();
-
-  MyIsEmpty = Standard_True;
+  myBounds.Clear();
 }
 
 // =======================================================================
@@ -187,16 +177,8 @@ Standard_Boolean Graphic3d_Group::IsEmpty() const
     return Standard_True;
   }
 
-  const Standard_ShortReal RL = ShortRealLast();
-  const Standard_ShortReal RF = ShortRealFirst();
-  const Standard_Boolean isEmpty = ((myBounds.XMin == RL) && (myBounds.YMin == RL)
-                                 && (myBounds.ZMin == RL) && (myBounds.XMax == RF)
-                                 && (myBounds.YMax == RF) && (myBounds.ZMax == RF));
-  if (isEmpty != MyIsEmpty)
-  {
-    ::Message::DefaultMessenger()->Send ("Graphic3d_Group: MyIsEmpty != IsEmpty()", Message_Trace);
-  }
-  return isEmpty;
+  return !myStructure->IsInfinite()
+      && !myBounds.IsValid();
 }
 
 // =======================================================================
@@ -206,12 +188,14 @@ Standard_Boolean Graphic3d_Group::IsEmpty() const
 void Graphic3d_Group::SetMinMaxValues (const Standard_Real theXMin, const Standard_Real theYMin, const Standard_Real theZMin,
                                        const Standard_Real theXMax, const Standard_Real theYMax, const Standard_Real theZMax)
 {
-  myBounds.XMin = Standard_ShortReal (theXMin);
-  myBounds.YMin = Standard_ShortReal (theYMin);
-  myBounds.ZMin = Standard_ShortReal (theZMin);
-  myBounds.XMax = Standard_ShortReal (theXMax);
-  myBounds.YMax = Standard_ShortReal (theYMax);
-  myBounds.ZMax = Standard_ShortReal (theZMax);
+  myBounds = Graphic3d_BndBox4f (Graphic3d_Vec4 (static_cast<Standard_ShortReal> (theXMin),
+                                                 static_cast<Standard_ShortReal> (theYMin),
+                                                 static_cast<Standard_ShortReal> (theZMin),
+                                                 1.0f),
+                                 Graphic3d_Vec4 (static_cast<Standard_ShortReal> (theXMax),
+                                                 static_cast<Standard_ShortReal> (theYMax),
+                                                 static_cast<Standard_ShortReal> (theZMax),
+                                                 1.0f));
 }
 
 // =======================================================================
@@ -247,14 +231,22 @@ void Graphic3d_Group::MinMaxCoord (Standard_Real& theXMin, Standard_Real& theYMi
     theXMin = theYMin = theZMin = ShortRealFirst();
     theXMax = theYMax = theZMax = ShortRealLast();
   }
+  else if (myBounds.IsValid())
+  {
+    const Graphic3d_Vec4& aMinPt = myBounds.CornerMin();
+    const Graphic3d_Vec4& aMaxPt = myBounds.CornerMax();
+    theXMin = Standard_Real (aMinPt.x());
+    theYMin = Standard_Real (aMinPt.y());
+    theZMin = Standard_Real (aMinPt.z());
+    theXMax = Standard_Real (aMaxPt.x());
+    theYMax = Standard_Real (aMaxPt.y());
+    theZMax = Standard_Real (aMaxPt.z());
+  }
   else
   {
-    theXMin = Standard_Real (myBounds.XMin);
-    theYMin = Standard_Real (myBounds.YMin);
-    theZMin = Standard_Real (myBounds.ZMin);
-    theXMax = Standard_Real (myBounds.XMax);
-    theYMax = Standard_Real (myBounds.YMax);
-    theZMax = Standard_Real (myBounds.ZMax);
+    // for consistency with old API
+    theXMin = theYMin = theZMin = ShortRealLast();
+    theXMax = theYMax = theZMax = ShortRealFirst();
   }
 }
 
@@ -269,10 +261,7 @@ void Graphic3d_Group::Update() const
     return;
   }
 
-  if (myStructure->StructureManager()->UpdateMode() == Aspect_TOU_ASAP)
-  {
-    myStructure->StructureManager()->Update();
-  }
+  myStructure->StructureManager()->Update (myStructure->StructureManager()->UpdateMode());
 }
 
 // =======================================================================
@@ -356,13 +345,15 @@ void Graphic3d_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_AspectFil
   // Back Material
   const Graphic3d_MaterialAspect& aBack = theAspFill->BackMaterial();
 
-  // Light specificity
-  ContextFillArea.Back.Shininess    = float (aBack.Shininess());
-  ContextFillArea.Back.Ambient      = float (aBack.Ambient());
-  ContextFillArea.Back.Diffuse      = float (aBack.Diffuse());
-  ContextFillArea.Back.Specular     = float (aBack.Specular());
-  ContextFillArea.Back.Transparency = float (aBack.Transparency());
-  ContextFillArea.Back.Emission     = float (aBack.Emissive());
+  // Material properties
+  ContextFillArea.Back.Shininess       = float (aBack.Shininess());
+  ContextFillArea.Back.Ambient         = float (aBack.Ambient());
+  ContextFillArea.Back.Diffuse         = float (aBack.Diffuse());
+  ContextFillArea.Back.Specular        = float (aBack.Specular());
+  ContextFillArea.Back.Transparency    = float (aBack.Transparency());
+  ContextFillArea.Back.Emission        = float (aBack.Emissive());
+  ContextFillArea.Back.RefractionIndex = float (aBack.RefractionIndex());
+  ContextFillArea.Back.BSDF            = aBack.BSDF();
 
   // Reflection mode
   ContextFillArea.Back.IsAmbient    = aBack.ReflectionMode (Graphic3d_TOR_AMBIENT)  ? 1 : 0;
@@ -397,13 +388,16 @@ void Graphic3d_Group::SetGroupPrimitivesAspect (const Handle(Graphic3d_AspectFil
 
   // Front Material
   const Graphic3d_MaterialAspect& aFront = theAspFill->FrontMaterial();
-  // Light specificity
-  ContextFillArea.Front.Shininess     = float (aFront.Shininess());
-  ContextFillArea.Front.Ambient       = float (aFront.Ambient());
-  ContextFillArea.Front.Diffuse       = float (aFront.Diffuse());
-  ContextFillArea.Front.Specular      = float (aFront.Specular());
-  ContextFillArea.Front.Transparency  = float (aFront.Transparency());
-  ContextFillArea.Front.Emission      = float (aFront.Emissive());
+
+  // Material properties
+  ContextFillArea.Front.Shininess       = float (aFront.Shininess());
+  ContextFillArea.Front.Ambient         = float (aFront.Ambient());
+  ContextFillArea.Front.Diffuse         = float (aFront.Diffuse());
+  ContextFillArea.Front.Specular        = float (aFront.Specular());
+  ContextFillArea.Front.Transparency    = float (aFront.Transparency());
+  ContextFillArea.Front.Emission        = float (aFront.Emissive());
+  ContextFillArea.Front.RefractionIndex = float (aFront.RefractionIndex());
+  ContextFillArea.Front.BSDF            = aFront.BSDF();
 
   // Reflection mode
   ContextFillArea.Front.IsAmbient     = aFront.ReflectionMode (Graphic3d_TOR_AMBIENT)  ? 1 : 0;
@@ -654,6 +648,9 @@ void Graphic3d_Group::SetPrimitivesAspect (const Handle(Graphic3d_AspectFillArea
 
   ContextFillArea.Back.EnvReflexion = float (aBack.EnvReflexion());
 
+  ContextFillArea.Back.RefractionIndex = float (aBack.RefractionIndex());
+  ContextFillArea.Back.BSDF = aBack.BSDF();
+
   // Front Material
   const Graphic3d_MaterialAspect& aFront = theAspFill->FrontMaterial();
   // Light specificity
@@ -695,6 +692,9 @@ void Graphic3d_Group::SetPrimitivesAspect (const Handle(Graphic3d_AspectFillArea
 
   ContextFillArea.Front.EnvReflexion  = float (aFront.EnvReflexion());
 
+  ContextFillArea.Front.RefractionIndex = float (aFront.RefractionIndex());
+  ContextFillArea.Front.BSDF = aFront.BSDF();
+
   ContextFillArea.IsDef = 1; // Material definition ok
 
   ContextFillArea.Texture.TextureMap   = theAspFill->TextureMap();
@@ -822,7 +822,7 @@ void Graphic3d_Group::GroupPrimitivesAspect (const Handle(Graphic3d_AspectLine3d
   Quantity_Color aColor;
   Graphic3d_MaterialAspect aFront, aBack;
 
-  const CALL_DEF_CONTEXTLINE& anAspLine = ContextLine.IsSet ? ContextLine : myStructure->CStructure()->ContextLine;
+  const CALL_DEF_CONTEXTLINE& anAspLine = ContextLine;
   aColor.SetValues (Standard_Real (anAspLine.Color.r),
                     Standard_Real (anAspLine.Color.g),
                     Standard_Real (anAspLine.Color.b), Quantity_TOC_RGB);
@@ -831,7 +831,7 @@ void Graphic3d_Group::GroupPrimitivesAspect (const Handle(Graphic3d_AspectLine3d
   theAspLine->SetWidth         (Standard_Real     (anAspLine.Width));
   theAspLine->SetShaderProgram (anAspLine.ShaderProgram);
 
-  const CALL_DEF_CONTEXTTEXT& anAspText = ContextText.IsSet ? ContextText : myStructure->CStructure()->ContextText;
+  const CALL_DEF_CONTEXTTEXT& anAspText = ContextText;
   aColor.SetValues (Standard_Real (anAspText.Color.r),
                     Standard_Real (anAspText.Color.g),
                     Standard_Real (anAspText.Color.b), Quantity_TOC_RGB);
@@ -847,7 +847,7 @@ void Graphic3d_Group::GroupPrimitivesAspect (const Handle(Graphic3d_AspectLine3d
   theAspText->SetDisplayType     (Aspect_TypeOfDisplayText (anAspText.DisplayType));
   theAspText->SetShaderProgram   (anAspText.ShaderProgram);
 
-  const CALL_DEF_CONTEXTMARKER& anAspMarker = ContextMarker.IsSet ? ContextMarker : myStructure->CStructure()->ContextMarker;
+  const CALL_DEF_CONTEXTMARKER& anAspMarker = ContextMarker;
   aColor.SetValues (Standard_Real (anAspMarker.Color.r),
                     Standard_Real (anAspMarker.Color.g),
                     Standard_Real (anAspMarker.Color.b), Quantity_TOC_RGB);
@@ -860,7 +860,7 @@ void Graphic3d_Group::GroupPrimitivesAspect (const Handle(Graphic3d_AspectLine3d
     theAspMarker->SetMarkerImage (ContextMarker.MarkerImage);
   }
 
-  const CALL_DEF_CONTEXTFILLAREA& anAspFill = ContextFillArea.IsSet ? ContextFillArea : myStructure->CStructure()->ContextFillArea;
+  const CALL_DEF_CONTEXTFILLAREA& anAspFill = ContextFillArea;
   // Interior
   theAspFill->SetInteriorStyle (Aspect_InteriorStyle (anAspFill.Style));
   aColor.SetValues (Standard_Real (anAspFill.IntColor.r),
@@ -910,6 +910,9 @@ void Graphic3d_Group::GroupPrimitivesAspect (const Handle(Graphic3d_AspectLine3d
 
   aBack.SetEnvReflexion (anAspFill.Back.EnvReflexion);
 
+  aBack.SetRefractionIndex (Standard_Real (anAspFill.Back.RefractionIndex));
+  aBack.SetBSDF (anAspFill.Back.BSDF);
+
   // Front Material
   aFront.SetShininess    (Standard_Real (anAspFill.Front.Shininess));
   aFront.SetAmbient      (Standard_Real (anAspFill.Front.Ambient));
@@ -944,6 +947,9 @@ void Graphic3d_Group::GroupPrimitivesAspect (const Handle(Graphic3d_AspectLine3d
 
   aFront.SetEnvReflexion (anAspFill.Front.EnvReflexion);
 
+  aFront.SetRefractionIndex (Standard_Real (anAspFill.Front.RefractionIndex));
+  aFront.SetBSDF (anAspFill.Front.BSDF);
+
   // Edges
   anAspFill.Edge == 1 ? theAspFill->SetEdgeOn() : theAspFill->SetEdgeOff();
   // Hatch
@@ -1016,7 +1022,6 @@ void Graphic3d_Group::AddPrimitiveArray (const Graphic3d_TypeOfPrimitiveArray th
     MyContainsFacet = Standard_True;
   }
 
-  MyIsEmpty = Standard_False;
   if (theToEvalMinMax)
   {
     const Standard_Integer aNbVerts = theAttribs->NbElements;
@@ -1036,10 +1041,7 @@ void Graphic3d_Group::AddPrimitiveArray (const Graphic3d_TypeOfPrimitiveArray th
           for (Standard_Integer aVertIter = 0; aVertIter < aNbVerts; ++aVertIter)
           {
             const Graphic3d_Vec2& aVert = *reinterpret_cast<const Graphic3d_Vec2* >(theAttribs->value (aVertIter) + anOffset);
-            if (aVert.x() < myBounds.XMin) myBounds.XMin = aVert.x();
-            if (aVert.y() < myBounds.YMin) myBounds.YMin = aVert.y();
-            if (aVert.x() > myBounds.XMax) myBounds.XMax = aVert.x();
-            if (aVert.y() > myBounds.YMax) myBounds.YMax = aVert.y();
+            myBounds.Add (Graphic3d_Vec4 (aVert.x(), aVert.y(), 0.0f, 1.0f));
           }
           break;
         }
@@ -1049,12 +1051,7 @@ void Graphic3d_Group::AddPrimitiveArray (const Graphic3d_TypeOfPrimitiveArray th
           for (Standard_Integer aVertIter = 0; aVertIter < aNbVerts; ++aVertIter)
           {
             const Graphic3d_Vec3& aVert = *reinterpret_cast<const Graphic3d_Vec3* >(theAttribs->value (aVertIter) + anOffset);
-            if (aVert.x() < myBounds.XMin) myBounds.XMin = aVert.x();
-            if (aVert.y() < myBounds.YMin) myBounds.YMin = aVert.y();
-            if (aVert.z() < myBounds.ZMin) myBounds.ZMin = aVert.z();
-            if (aVert.x() > myBounds.XMax) myBounds.XMax = aVert.x();
-            if (aVert.y() > myBounds.YMax) myBounds.YMax = aVert.y();
-            if (aVert.z() > myBounds.ZMax) myBounds.ZMax = aVert.z();
+            myBounds.Add (Graphic3d_Vec4 (aVert.x(), aVert.y(), aVert.z(), 1.0f));
           }
           break;
         }
@@ -1079,31 +1076,6 @@ void Graphic3d_Group::Marker (const Graphic3d_Vertex& thePoint,
   AddPrimitiveArray (aPoints, theToEvalMinMax);
 }
 
-// =======================================================================
-// function : UserDraw
-// purpose  :
-// =======================================================================
-void Graphic3d_Group::UserDraw (const Standard_Address /*theObject*/,
-                                const Standard_Boolean /*theToEvalMinMax*/,
-                                const Standard_Boolean theContainsFacet)
-{
-  if (IsDeleted())
-  {
-    return;
-  }
-
-  // Without this modification, the group assumes the primitive contains
-  // no polygons and does not require the Z-buffer for display.
-  if (!MyContainsFacet && theContainsFacet)
-  {
-    myStructure->GroupsWithFacet (1);
-    MyContainsFacet = Standard_True;
-  }
-
-  MyIsEmpty = Standard_False;
-  Update();
-}
-
 // =======================================================================
 // function : Text
 // purpose  :
@@ -1122,17 +1094,15 @@ void Graphic3d_Group::Text (const Standard_CString                  /*theText*/,
     return;
   }
 
-  MyIsEmpty  = Standard_False;
   if (theToEvalMinMax)
   {
     Standard_ShortReal x, y, z;
     thePoint.Coord (x, y, z);
-    if (x < myBounds.XMin) myBounds.XMin = x;
-    if (y < myBounds.YMin) myBounds.YMin = y;
-    if (z < myBounds.ZMin) myBounds.ZMin = z;
-    if (x > myBounds.XMax) myBounds.XMax = x;
-    if (y > myBounds.YMax) myBounds.YMax = y;
-    if (z > myBounds.ZMax) myBounds.ZMax = z;
+    myStructure->CStructure()->Is2dText = Standard_True;
+    myBounds.Add (Graphic3d_Vec4 (static_cast<Standard_ShortReal> (x),
+                                  static_cast<Standard_ShortReal> (y),
+                                  static_cast<Standard_ShortReal> (z),
+                                  1.0f));
   }
   Update();
 }
@@ -1168,6 +1138,62 @@ void Graphic3d_Group::Text (const TCollection_ExtendedString&       theText,
         theTp, theHta, theVta, theToEvalMinMax);
 }
 
+// =======================================================================
+// function : Text
+// purpose  :
+// =======================================================================
+void Graphic3d_Group::Text (const TCollection_ExtendedString&       theText,
+                            const gp_Ax2&                           theOrientation,
+                            const Standard_Real                     theHeight,
+                            const Quantity_PlaneAngle               theAngle,
+                            const Graphic3d_TextPath                theTP,
+                            const Graphic3d_HorizontalTextAlignment theHTA,
+                            const Graphic3d_VerticalTextAlignment   theVTA,
+                            const Standard_Boolean                  theToEvalMinMax,
+                            const Standard_Boolean                  theHasOwnAnchor)
+{
+  const NCollection_String aText ((Standard_Utf16Char*)(theText.ToExtString()));
+  Text (aText.ToCString(),
+        theOrientation,
+        theHeight,
+        theAngle,
+        theTP,
+        theHTA,
+        theVTA,
+        theToEvalMinMax,
+        theHasOwnAnchor);
+}
+
+// =======================================================================
+// function : Text
+// purpose  :
+// =======================================================================
+void Graphic3d_Group::Text (const Standard_CString                  /*theText*/,
+                            const gp_Ax2&                           theOrientation,
+                            const Standard_Real                     /*theHeight*/,
+                            const Quantity_PlaneAngle               /*theAngle*/,
+                            const Graphic3d_TextPath                /*theTp*/,
+                            const Graphic3d_HorizontalTextAlignment /*theHta*/,
+                            const Graphic3d_VerticalTextAlignment   /*theVta*/,
+                            const Standard_Boolean                  theToEvalMinMax,
+                            const Standard_Boolean                  /*theHasOwnAnchor*/)
+{
+  if (IsDeleted())
+  {
+    return;
+  }
+
+  if (theToEvalMinMax)
+  {
+    myStructure->CStructure()->Is2dText = Standard_False;
+    myBounds.Add (Graphic3d_Vec4 (static_cast<Standard_ShortReal> (theOrientation.Location().X()),
+                                  static_cast<Standard_ShortReal> (theOrientation.Location().Y()),
+                                  static_cast<Standard_ShortReal> (theOrientation.Location().Z()),
+                                  1.0f));
+  }
+  Update();
+}
+
 // =======================================================================
 // function : Text
 // purpose  :
@@ -1181,3 +1207,39 @@ void Graphic3d_Group::Text (const TCollection_ExtendedString& theText,
   Text (aText.ToCString(), thePoint, theHeight, 0.0,
         Graphic3d_TP_RIGHT, Graphic3d_HTA_LEFT, Graphic3d_VTA_BOTTOM, theToEvalMinMax);
 }
+
+// =======================================================================
+// function : SetClosed
+// purpose  :
+// =======================================================================
+void Graphic3d_Group::SetClosed (const Standard_Boolean theIsClosed)
+{
+  myIsClosed = theIsClosed;
+}
+
+// =======================================================================
+// function : IsClosed
+// purpose  :
+// =======================================================================
+Standard_Boolean Graphic3d_Group::IsClosed() const
+{
+  return myIsClosed;
+}
+
+//=======================================================================
+//function : BoundingBox
+//purpose  :
+//=======================================================================
+const Graphic3d_BndBox4f& Graphic3d_Group::BoundingBox() const
+{
+  return myBounds;
+}
+
+//=======================================================================
+//function : ChangeBoundingBox
+//purpose  :
+//=======================================================================
+Graphic3d_BndBox4f& Graphic3d_Group::ChangeBoundingBox()
+{
+  return myBounds;
+}