0024837: Visualization - revise design and implementation of connected Interactive...
[occt.git] / src / Graphic3d / Graphic3d_Structure.cxx
index a2fda6b..e66e2ec 100644 (file)
@@ -114,6 +114,32 @@ void Graphic3d_Structure::Clear (const Standard_Boolean theWithDestruction)
   Update();
 }
 
+//=======================================================================
+//function : CalculateBoundBox
+//purpose  : Calculates AABB of a structure.
+//=======================================================================
+void Graphic3d_Structure::CalculateBoundBox()
+{
+  Graphic3d_BndBox4d aBox;
+  addTransformed (aBox, Standard_True);
+  if (aBox.IsValid() && myCStructure->TransformPersistence.Flag == 0)
+  {
+    Graphic3d_Vec4 aMinPt (RealToShortReal (aBox.CornerMin().x()),
+                           RealToShortReal (aBox.CornerMin().y()),
+                           RealToShortReal (aBox.CornerMin().z()),
+                           1.0f);
+    Graphic3d_Vec4 aMaxPt (RealToShortReal (aBox.CornerMax().x()),
+                           RealToShortReal (aBox.CornerMax().y()),
+                           RealToShortReal (aBox.CornerMax().z()),
+                           1.0f);
+    myCStructure->ChangeBoundingBox() = Graphic3d_BndBox4f (aMinPt, aMaxPt);
+  }
+  else
+  {
+    myCStructure->ChangeBoundingBox().Clear();
+  }
+}
+
 //=============================================================================
 //function : Remove
 //purpose  :
@@ -150,8 +176,6 @@ void Graphic3d_Structure::Remove()
     ((Graphic3d_Structure *)(myAncestors.ChangeValue (aStructIter)))->Remove (APtr, Graphic3d_TOC_DESCENDANT);
   }
 
-  myCStructure->ContainsFacet = 0;
-
   // Destruction of me in the graphic library
   const Standard_Integer aStructId = myCStructure->Id;
   myCStructure->GraphicDriver()->RemoveStructure (myCStructure);
@@ -182,6 +206,15 @@ void Graphic3d_Structure::Display()
   myCStructure->visible = 1;
 }
 
+//=============================================================================
+//function : SetIsForHighlight
+//purpose  :
+//=============================================================================
+void Graphic3d_Structure::SetIsForHighlight (const Standard_Boolean isForHighlight)
+{
+  myCStructure->IsForHighlight = isForHighlight;
+}
+
 //=============================================================================
 //function : Display
 //purpose  :
@@ -1375,6 +1408,7 @@ void Graphic3d_Structure::Connect (const Handle(Graphic3d_Structure)& theStructu
       }
 
       myDescendants.Append (theStructure.operator->());
+      CalculateBoundBox();
       theStructure->Connect (this, Graphic3d_TOC_ANCESTOR);
 
       GraphicConnect (theStructure);
@@ -1395,6 +1429,7 @@ void Graphic3d_Structure::Connect (const Handle(Graphic3d_Structure)& theStructu
       }
 
       myAncestors.Append (theStructure.operator->());
+      CalculateBoundBox();
       theStructure->Connect (this, Graphic3d_TOC_DESCENDANT);
 
       // myGraphicDriver->Connect is called in case if connection between parent and child
@@ -1422,6 +1457,8 @@ void Graphic3d_Structure::Disconnect (const Handle(Graphic3d_Structure)& theStru
       GraphicDisconnect (theStructure);
       myStructureManager->Disconnect (this, theStructure);
 
+      CalculateBoundBox();
+
       Update();
       return;
     }
@@ -1434,6 +1471,7 @@ void Graphic3d_Structure::Disconnect (const Handle(Graphic3d_Structure)& theStru
     {
       myAncestors.Remove (anIter);
       theStructure->Disconnect (this);
+      CalculateBoundBox();
       // no call of myGraphicDriver->Disconnect in case of an ancestor
       return;
     }
@@ -1608,6 +1646,7 @@ void Graphic3d_Structure::Transform (TColStd_Array2OfReal& theMatrix) const
   }
 }
 
+
 //=============================================================================
 //function : MinMaxValues
 //purpose  :
@@ -1620,89 +1659,9 @@ void Graphic3d_Structure::MinMaxValues (Standard_Real& theXMin,
                                         Standard_Real& theZMax,
                                         const Standard_Boolean theToIgnoreInfiniteFlag) const
 {
-  if (IsEmpty())
-  {
-    return;
-  }
-
-  Standard_Real aXMin, aYMin, aZMin, aXMax, aYMax, aZMax;
-  MinMaxCoord (aXMin, aYMin, aZMin, aXMax, aYMax, aZMax);
-
-  // Infinite boundaries corresponding to empty structure or
-  // non-empty structure, without any primitives specified
-  if (aXMin == RealFirst() && aYMin == RealFirst() && aZMin == RealFirst() &&
-      aXMax == RealLast()  && aYMax == RealLast()  && aZMax == RealLast())
-  {
-    theXMin = RealFirst();
-    theYMin = RealFirst();
-    theZMin = RealFirst();
-    theXMax = RealLast();
-    theYMax = RealLast();
-    theZMax = RealLast();
-    return;
-  }
-
-  // Handle flag, which specifies that structure should be considered as infinite
-  if (IsInfinite() && !theToIgnoreInfiniteFlag)
-  {
-    Graphic3d_Vertex aVertexMin (aXMin, aYMin, aZMin);
-    Graphic3d_Vertex aVertexMax (aXMax, aYMax, aZMax);
-    const Standard_Real aDistance = aVertexMin.Distance (aVertexMax);
-
-    // Special case for infinite line:
-    // Bounding borders of infinite line has been
-    // calculated as own point in center of this line
-    if (aDistance >= 500000.0)
-    {
-      theXMin = theXMax = 0.5 * (aXMin + aXMax);
-      theYMin = theYMax = 0.5 * (aYMin + aYMax);
-      theZMin = theZMax = 0.5 * (aZMin + aZMax);
-      return;
-    }
-
-    theXMin = RealFirst();
-    theYMin = RealFirst();
-    theZMin = RealFirst();
-    theXMax = RealLast();
-    theYMax = RealLast();
-    theZMax = RealLast();
-    return;
-  }
-
-  // Min-Max values of the descendant structures
-  Standard_Real aDescXMin = RealLast();
-  Standard_Real aDescYMin = RealLast();
-  Standard_Real aDescZMin = RealLast();
-  Standard_Real aDescXMax = RealFirst();
-  Standard_Real aDescYMax = RealFirst();
-  Standard_Real aDescZMax = RealFirst();
-  for (Standard_Integer aStructIt = 1; aStructIt <= myDescendants.Length(); aStructIt++)
-  {
-    Graphic3d_Structure* aStructure = (Graphic3d_Structure*) myDescendants.Value (aStructIt);
-    aStructure->MinMaxValues (aXMin, aYMin, aZMin, aXMax, aYMax, aZMax);
-    aDescXMin = Min (aXMin, aDescXMin);
-    aDescYMin = Min (aYMin, aDescYMin);
-    aDescZMin = Min (aZMin, aDescZMin);
-    aDescXMax = Max (aXMax, aDescXMax);
-    aDescYMax = Max (aYMax, aDescYMax);
-    aDescZMax = Max (aZMax, aDescZMax);
-  }
-
-  if (aDescXMin != RealLast()  || aDescYMin != RealLast()  ||
-      aDescZMin != RealLast()  || aDescXMax != RealFirst() ||
-      aDescYMax != RealFirst() || aDescZMax != RealFirst())
-  {
-    aXMin = Min (aDescXMin, aXMin);
-    aYMin = Min (aDescYMin, aYMin);
-    aZMin = Min (aDescZMin, aZMin);
-    aXMax = Max (aDescXMax, aXMax);
-    aYMax = Max (aDescYMax, aYMax);
-    aZMax = Max (aDescZMax, aZMax);
-  }
-
-  // Case impossible as it would mean that the structure is empty or infinite
-  if (aXMin == RealFirst() && aYMin == RealFirst() && aZMin == RealFirst() &&
-      aXMax == RealLast()  && aYMax == RealLast()  && aZMax == RealLast())
+  Graphic3d_BndBox4d aBox;
+  addTransformed (aBox, theToIgnoreInfiniteFlag);
+  if (!aBox.IsValid())
   {
     theXMin = RealFirst();
     theYMin = RealFirst();
@@ -1713,15 +1672,12 @@ void Graphic3d_Structure::MinMaxValues (Standard_Real& theXMin,
     return;
   }
 
-  TColStd_Array2OfReal aTrsf(0, 3, 0, 3);
-  Transform (aTrsf);
-  TransformBoundaries (aTrsf, aXMin, aYMin, aZMin, aXMax, aYMax, aZMax);
-  theXMin = aXMin;
-  theYMin = aYMin;
-  theZMin = aZMin;
-  theXMax = aXMax;
-  theYMax = aYMax;
-  theZMax = aZMax;
+  theXMin = aBox.CornerMin().x();
+  theYMin = aBox.CornerMin().y();
+  theZMin = aBox.CornerMin().z();
+  theXMax = aBox.CornerMax().x();
+  theYMax = aBox.CornerMax().y();
+  theZMax = aBox.CornerMax().z();
 }
 
 //=============================================================================
@@ -1756,6 +1712,7 @@ void Graphic3d_Structure::SetTransformPersistence (const Graphic3d_TransModeFlag
   myCStructure->TransformPersistence.Point.y = float (thePoint.Y());
   myCStructure->TransformPersistence.Point.z = float (thePoint.Z());
   myCStructure->UpdateAspects();
+  CalculateBoundBox();
 
   myCStructure->TransformPersistence.IsSet = 1;
 }
@@ -1855,154 +1812,100 @@ Handle(Graphic3d_StructureManager) Graphic3d_Structure::StructureManager() const
 }
 
 //=============================================================================
-//function : MinMaxCoord
+//function : minMaxCoord
 //purpose  :
 //=============================================================================
-void Graphic3d_Structure::MinMaxCoord (Standard_Real& theXMin,
-                                       Standard_Real& theYMin,
-                                       Standard_Real& theZMin,
-                                       Standard_Real& theXMax,
-                                       Standard_Real& theYMax,
-                                       Standard_Real& theZMax) const
+Graphic3d_BndBox4f Graphic3d_Structure::minMaxCoord (const Standard_Boolean theToIgnoreInfiniteFlag) const
 {
-  if (IsEmpty())
-  {
-    theXMin = RealFirst();
-    theYMin = RealFirst();
-    theZMin = RealFirst();
-    theXMax = RealLast();
-    theYMax = RealLast();
-    theZMax = RealLast();
-    return;
-  }
-
-  Standard_Real aXMin = RealLast();
-  Standard_Real aYMin = RealLast();
-  Standard_Real aZMin = RealLast();
-  Standard_Real aXMax = RealFirst();
-  Standard_Real aYMax = RealFirst();
-  Standard_Real aZMax = RealFirst();
-  Standard_Real aGroupXMin, aGroupYMin, aGroupZMin, aGroupXMax, aGroupYMax, aGroupZMax;
+  Graphic3d_BndBox4f aBnd;
   for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (myCStructure->Groups()); aGroupIter.More(); aGroupIter.Next())
   {
-    const Handle(Graphic3d_Group)& aGroup = aGroupIter.Value();
-    if (aGroup->IsEmpty())
+    if (!theToIgnoreInfiniteFlag)
     {
-      continue;
+      aBnd.Combine (aGroupIter.Value()->BoundingBox());
+    }
+    else
+    {
+      Graphic3d_BndBox4f aValidBnd (aGroupIter.Value()->BoundingBox().CornerMin(),
+                                    aGroupIter.Value()->BoundingBox().CornerMax());
+      aBnd.Combine (aValidBnd);
     }
-
-    aGroup->MinMaxValues (aGroupXMin, aGroupYMin, aGroupZMin, aGroupXMax, aGroupYMax, aGroupZMax);
-    aXMin = Min (aXMin, aGroupXMin);
-    aYMin = Min (aYMin, aGroupYMin);
-    aZMin = Min (aZMin, aGroupZMin);
-    aXMax = Max (aXMax, aGroupXMax);
-    aYMax = Max (aYMax, aGroupYMax);
-    aZMax = Max (aZMax, aGroupZMax);
-  }
-
-  // Case impossible as it would mean that the structure is empty
-  if (aXMin == RealLast()  && aYMin == RealLast()  && aZMin == RealLast() &&
-      aXMax == RealFirst() && aYMax == RealFirst() && aZMax == RealFirst())
-  {
-    theXMin = RealFirst();
-    theYMin = RealFirst();
-    theZMin = RealFirst();
-    theXMax = RealLast();
-    theYMax = RealLast();
-    theZMax = RealLast();
   }
-
-  theXMin = aXMin;
-  theYMin = aYMin;
-  theZMin = aZMin;
-  theXMax = aXMax;
-  theYMax = aYMax;
-  theZMax = aZMax;
+  return aBnd;
 }
 
 //=============================================================================
-//function : MinMaxCoordWithDescendants
+//function : addTransformed
 //purpose  :
 //=============================================================================
-void Graphic3d_Structure::MinMaxCoordWithDescendants (Standard_Real& theXMin,
-                                                      Standard_Real& theYMin,
-                                                      Standard_Real& theZMin,
-                                                      Standard_Real& theXMax,
-                                                      Standard_Real& theYMax,
-                                                      Standard_Real& theZMax) const
+void Graphic3d_Structure::getBox (Graphic3d_BndBox4d&    theBox,
+                                  const Standard_Boolean theToIgnoreInfiniteFlag) const
 {
-  if (IsEmpty())
+  Graphic3d_BndBox4f aBoxF = minMaxCoord (theToIgnoreInfiniteFlag);
+  if (aBoxF.IsValid())
   {
-    theXMin = RealFirst();
-    theYMin = RealFirst();
-    theZMin = RealFirst();
-    theXMax = RealLast();
-    theYMax = RealLast();
-    theZMax = RealLast();
-    return;
+    theBox = Graphic3d_BndBox4d (Graphic3d_Vec4d ((Standard_Real )aBoxF.CornerMin().x(),
+                                                  (Standard_Real )aBoxF.CornerMin().y(),
+                                                  (Standard_Real )aBoxF.CornerMin().z(),
+                                                  (Standard_Real )aBoxF.CornerMin().w()),
+                                 Graphic3d_Vec4d ((Standard_Real )aBoxF.CornerMax().x(),
+                                                  (Standard_Real )aBoxF.CornerMax().y(),
+                                                  (Standard_Real )aBoxF.CornerMax().z(),
+                                                  (Standard_Real )aBoxF.CornerMax().w()));
+    if (IsInfinite()
+    && !theToIgnoreInfiniteFlag)
+    {
+      const Graphic3d_Vec4d aDiagVec = theBox.CornerMax() - theBox.CornerMin();
+      if (aDiagVec.xyz().SquareModulus() >= 500000.0 * 500000.0)
+      {
+        // bounding borders of infinite line has been calculated as own point in center of this line
+        theBox = Graphic3d_BndBox4d ((theBox.CornerMin() + theBox.CornerMax()) * 0.5);
+      }
+      else
+      {
+        theBox = Graphic3d_BndBox4d (Graphic3d_Vec4d (RealFirst(), RealFirst(), RealFirst(), 1.0),
+                                     Graphic3d_Vec4d (RealLast(),  RealLast(),  RealLast(),  1.0));
+        return;
+      }
+    }
   }
+}
 
-  Standard_Real aXMin, aYMin, aZMin, aXMax, aYMax, aZMax;
-  MinMaxCoord (aXMin, aYMin, aZMin, aXMax, aYMax, aZMax);
+//=============================================================================
+//function : addTransformed
+//purpose  :
+//=============================================================================
+void Graphic3d_Structure::addTransformed (Graphic3d_BndBox4d&    theBox,
+                                          const Standard_Boolean theToIgnoreInfiniteFlag) const
+{
+  Graphic3d_BndBox4d aCombinedBox, aBox;
+  getBox (aCombinedBox, theToIgnoreInfiniteFlag);
 
-  // Min-Max of the descendant structures
-  Standard_Real aDescXMin = RealLast();
-  Standard_Real aDescYMin = RealLast();
-  Standard_Real aDescZMin = RealLast();
-  Standard_Real aDescXMax = RealFirst();
-  Standard_Real aDescYMax = RealFirst();
-  Standard_Real aDescZMax = RealFirst();
-  for (Standard_Integer aStructIt = 1; aStructIt <= myDescendants.Length(); aStructIt++)
+  for (Standard_Integer aStructIt = 1; aStructIt <= myDescendants.Length(); ++aStructIt)
   {
-    Graphic3d_Structure* aStructure = (Graphic3d_Structure*) myDescendants.Value (aStructIt);
-    if (aStructure->IsEmpty())
-    {
-      continue;
-    }
-
-    aStructure->MinMaxCoordWithDescendants (aXMin, aYMin, aZMin, aXMax, aYMax, aZMax);
-    aDescXMin = Min (aXMin, aDescXMin);
-    aDescYMin = Min (aYMin, aDescYMin);
-    aDescZMin = Min (aZMin, aDescZMin);
-    aDescXMax = Max (aXMax, aDescXMax);
-    aDescYMax = Max (aYMax, aDescYMax);
-    aDescZMax = Max (aZMax, aDescZMax);
+    const Graphic3d_Structure* aStruct = (const Graphic3d_Structure* )myDescendants.Value (aStructIt);
+    aStruct->getBox (aBox, theToIgnoreInfiniteFlag);
+    aCombinedBox.Combine (aBox);
   }
 
-  if (aDescXMin != RealLast()  || aDescYMin != RealLast()  ||
-      aDescZMin != RealLast()  || aDescXMax != RealFirst() ||
-      aDescYMax != RealFirst() || aDescZMax != RealFirst())
+  aBox = aCombinedBox;
+  if (aBox.IsValid())
   {
-    TColStd_Array2OfReal aTrsf(0, 3, 0, 3);
+    TColStd_Array2OfReal aTrsf (0, 3, 0, 3);
     Transform (aTrsf);
-    TransformBoundaries (aTrsf, aDescXMin, aDescYMin, aDescZMin, aDescXMax, aDescYMax, aDescZMax);
+    TransformBoundaries (aTrsf, aBox.CornerMin().x(), aBox.CornerMin().y(), aBox.CornerMin().z(),
+                                aBox.CornerMax().x(), aBox.CornerMax().y(), aBox.CornerMax().z());
 
-    aXMin = Min (aDescXMin, aXMin);
-    aYMin = Min (aDescYMin, aYMin);
-    aZMin = Min (aDescZMin, aZMin);
-    aXMax = Max (aDescXMax, aXMax);
-    aYMax = Max (aDescYMax, aYMax);
-    aZMax = Max (aDescZMax, aZMax);
-  }
-
-  // Case impossible as it would mean that the structure is empty
-  if (aXMin == RealLast()  && aYMin == RealLast()  && aZMin == RealLast() &&
-      aXMax == RealFirst() && aYMax == RealFirst() && aZMax == RealFirst())
-  {
-    theXMin = RealFirst();
-    theYMin = RealFirst();
-    theZMin = RealFirst();
-    theXMax = RealLast();
-    theYMax = RealLast();
-    theZMax = RealLast();
+    // if box is still valid after transformation
+    if (aBox.IsValid())
+    {
+      theBox.Combine (aBox);
+    }
+    else // it was infinite, return untransformed
+    {
+      theBox.Combine (aCombinedBox);
+    }
   }
-
-  theXMin = aXMin;
-  theYMin = aYMin;
-  theZMin = aZMin;
-  theXMax = aXMax;
-  theYMax = aYMax;
-  theZMax = aZMax;
 }
 
 //=============================================================================
@@ -2384,27 +2287,10 @@ void Graphic3d_Structure::GraphicHighlight (const Aspect_TypeOfHighlightMethod t
     }
     case Aspect_TOHM_BOUNDBOX:
     {
-      Standard_Real XMin, YMin, ZMin, XMax, YMax, ZMax;
-      if (IsEmpty() || IsInfinite())
-      {
-        // Empty or infinite structure
-        XMin = YMin = ZMin = 0.0;
-        XMax = YMax = ZMax = 0.0;
-      }
-      else
-      {
-        MinMaxCoordWithDescendants (XMin, YMin, ZMin, XMax, YMax, ZMax);
-      }
-      myCStructure->BoundBox.Pmin.x  = float (XMin);
-      myCStructure->BoundBox.Pmin.y  = float (YMin);
-      myCStructure->BoundBox.Pmin.z  = float (ZMin);
-      myCStructure->BoundBox.Pmax.x  = float (XMax);
-      myCStructure->BoundBox.Pmax.y  = float (YMax);
-      myCStructure->BoundBox.Pmax.z  = float (ZMax);
       myHighlightColor.Values (anRGB[0], anRGB[1], anRGB[2], Quantity_TOC_RGB);
-      myCStructure->BoundBox.Color.r = float (anRGB[0]);
-      myCStructure->BoundBox.Color.g = float (anRGB[1]);
-      myCStructure->BoundBox.Color.b = float (anRGB[2]);
+      myCStructure->HighlightColor.r = float (anRGB[0]);
+      myCStructure->HighlightColor.g = float (anRGB[1]);
+      myCStructure->HighlightColor.b = float (anRGB[2]);
       myCStructure->HighlightWithBndBox (this, Standard_True);
       break;
     }
@@ -2470,15 +2356,6 @@ void Graphic3d_Structure::SetComputeVisual (const Graphic3d_TypeOfStructure theV
   }
 }
 
-//=============================================================================
-//function : Plot
-//purpose  :
-//=============================================================================
-void Graphic3d_Structure::Plot (const Handle(Graphic3d_Plotter)& )
-{
-  //
-}
-
 //=============================================================================
 //function : SetHLRValidation
 //purpose  :
@@ -2540,3 +2417,21 @@ const Graphic3d_SequenceOfHClipPlane& Graphic3d_Structure::GetClipPlanes() const
 {
   return myCStructure->ClipPlanes();
 }
+
+//=======================================================================
+//function : SetMutable
+//purpose  :
+//=======================================================================
+void Graphic3d_Structure::SetMutable (const Standard_Boolean theIsMutable)
+{
+  myCStructure->IsMutable = theIsMutable;
+}
+
+//=======================================================================
+//function : IsMutable
+//purpose  :
+//=======================================================================
+Standard_Boolean Graphic3d_Structure::IsMutable() const
+{
+  return myCStructure->IsMutable;
+}