0030232: Visualization, StdPrs_BndBox - support Bnd_OBB in addition to Bnd_Box IR-2018-10-12
authorkgv <kgv@opencascade.com>
Thu, 11 Oct 2018 13:05:32 +0000 (16:05 +0300)
committerapn <apn@opencascade.com>
Fri, 12 Oct 2018 14:22:45 +0000 (17:22 +0300)
src/Bnd/Bnd_OBB.hxx
src/StdPrs/StdPrs_BndBox.cxx
src/StdPrs/StdPrs_BndBox.hxx

index 474af04..d40d22c 100644 (file)
@@ -22,6 +22,7 @@
 #include <Standard_Boolean.hxx>
 
 #include <Bnd_Box.hxx>
+#include <gp_Ax3.hxx>
 #include <gp_Dir.hxx>
 #include <gp_Pnt.hxx>
 #include <gp_XYZ.hxx>
@@ -136,7 +137,15 @@ public:
     myAxes[2] = theZDirection.XYZ();
     myHDims[2] = theHZSize;
   }
-  
+
+  //! Returns the local coordinates system of this oriented box.
+  //! So that applying it to axis-aligned box ((-XHSize, -YHSize, -ZHSize), (XHSize, YHSize, ZHSize)) will produce this oriented box.
+  //! @code
+  //!   gp_Trsf aLoc;
+  //!   aLoc.SetTransformation (theOBB.Position(), gp::XOY());
+  //! @endcode
+  gp_Ax3 Position() const { return gp_Ax3 (myCenter, ZDirection(), XDirection()); }
+
   //! Returns the center of OBB
   const gp_XYZ& Center() const
   {
@@ -267,7 +276,8 @@ public:
   //! (which it was created from) and theP.
   Standard_EXPORT void Add(const gp_Pnt& theP);
 
-  protected:
+protected:
+
     void ProcessOnePoint(const gp_Pnt& theP)
     {
       myIsAABox = Standard_True;
index 3c1cf15..cbe3f20 100644 (file)
 
 #include <StdPrs_BndBox.hxx>
 
-#include <Aspect_TypeOfLine.hxx>
-#include <Graphic3d_AspectLine3d.hxx>
-#include <Graphic3d_ArrayOfPolylines.hxx>
 #include <Prs3d_LineAspect.hxx>
-#include <Quantity_Color.hxx>
-
-namespace
-{
-  static const Standard_Integer THE_INDICES[][3] =
-  { { 0, 0, 0 }, { 1, 0, 0 }, { 1, 0, 1 }, { 0, 0, 1 },
-    { 0, 1, 1 }, { 1, 1, 1 }, { 1, 1, 0 }, { 0, 1, 0 },
-    { 0, 0, 0 }, { 0, 0, 1 }, { 1, 0, 1 }, { 1, 1, 1 },
-    { 0, 1, 1 }, { 0, 1, 0 }, { 1, 1, 0 }, { 1, 0, 0 } };
-}
 
 //=======================================================================
 //function : Add
@@ -38,25 +25,30 @@ void StdPrs_BndBox::Add (const Handle(Prs3d_Presentation)& thePresentation,
                          const Bnd_Box&                    theBndBox,
                          const Handle(Prs3d_Drawer)&       theDrawer)
 {
-  if (theBndBox.IsVoid())
+  if (!theBndBox.IsVoid())
   {
-    return;
+    Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (thePresentation);
+    aGroup->SetGroupPrimitivesAspect (new Graphic3d_AspectLine3d (theDrawer->LineAspect()->Aspect()->Color(),
+                                                                  Aspect_TOL_DOTDASH,
+                                                                  theDrawer->LineAspect()->Aspect()->Width()));
+    aGroup->AddPrimitiveArray (FillSegments (theBndBox));
   }
+}
 
-  Standard_Real X[2], Y[2], Z[2];
-  theBndBox.Get (X[0], Y[0], Z[0], X[1], Y[1], Z[1]);
-
-  Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (thePresentation);
-  Quantity_Color aColor = theDrawer->LineAspect()->Aspect()->Color();
-  Standard_Real  aWidth = theDrawer->LineAspect()->Aspect()->Width();
-  aGroup->SetGroupPrimitivesAspect (new Graphic3d_AspectLine3d (aColor, Aspect_TOL_DOTDASH, aWidth));
-
-  Handle(Graphic3d_ArrayOfPolylines) aPolyline = new Graphic3d_ArrayOfPolylines(16);
-  for(Standard_Integer aVertIter = 0; aVertIter < 16; ++aVertIter)
+//=======================================================================
+//function : Add
+//purpose  :
+//=======================================================================
+void StdPrs_BndBox::Add (const Handle(Prs3d_Presentation)& thePresentation,
+                         const Bnd_OBB&                    theBndBox,
+                         const Handle(Prs3d_Drawer)&       theDrawer)
+{
+  if (!theBndBox.IsVoid())
   {
-    aPolyline->AddVertex (X[THE_INDICES[aVertIter][0]],
-                          Y[THE_INDICES[aVertIter][1]],
-                          Z[THE_INDICES[aVertIter][2]]);
+    Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (thePresentation);
+    aGroup->SetGroupPrimitivesAspect (new Graphic3d_AspectLine3d (theDrawer->LineAspect()->Aspect()->Color(),
+                                                                  Aspect_TOL_DOTDASH,
+                                                                  theDrawer->LineAspect()->Aspect()->Width()));
+    aGroup->AddPrimitiveArray (FillSegments (theBndBox));
   }
-  aGroup->AddPrimitiveArray (aPolyline);
 }
index a68e999..307b1b1 100644 (file)
 #ifndef _StdPrs_BndBox_H__
 #define _StdPrs_BndBox_H__
 
-#include <Prs3d_Root.hxx>
+#include <Bnd_OBB.hxx>
+#include <Graphic3d_ArrayOfSegments.hxx>
+#include <Graphic3d_ArrayOfTriangles.hxx>
 #include <Prs3d_Drawer.hxx>
 #include <Prs3d_Presentation.hxx>
-#include <Bnd_Box.hxx>
+#include <Prs3d_Root.hxx>
 
 //! Tool for computing bounding box presentation.
 class StdPrs_BndBox : public Prs3d_Root
@@ -33,6 +35,114 @@ public:
   Standard_EXPORT static void Add (const Handle(Prs3d_Presentation)& thePresentation,
                                    const Bnd_Box& theBndBox,
                                    const Handle(Prs3d_Drawer)& theDrawer);
+
+  //! Computes presentation of a bounding box.
+  //! @param thePresentation [in] the presentation.
+  //! @param theBndBox [in] the bounding box.
+  //! @param theDrawer [in] the drawer.
+  Standard_EXPORT static void Add (const Handle(Prs3d_Presentation)& thePresentation,
+                                   const Bnd_OBB& theBndBox,
+                                   const Handle(Prs3d_Drawer)& theDrawer);
+
+public:
+
+  //! Create primitive array with line segments for displaying a box.
+  //! @param theBox [in] the box to add
+  static Handle(Graphic3d_ArrayOfSegments) FillSegments (const Bnd_OBB& theBox)
+  {
+    if (theBox.IsVoid())
+    {
+      return Handle(Graphic3d_ArrayOfSegments)();
+    }
+
+    Handle(Graphic3d_ArrayOfSegments) aSegs = new Graphic3d_ArrayOfSegments (8, 12 * 2);
+    FillSegments (aSegs, theBox);
+    return aSegs;
+  }
+
+  //! Create primitive array with line segments for displaying a box.
+  //! @param theBox [in] the box to add
+  static Handle(Graphic3d_ArrayOfSegments) FillSegments (const Bnd_Box& theBox)
+  {
+    if (theBox.IsVoid())
+    {
+      return Handle(Graphic3d_ArrayOfSegments)();
+    }
+
+    Handle(Graphic3d_ArrayOfSegments) aSegs = new Graphic3d_ArrayOfSegments (8, 12 * 2);
+    FillSegments (aSegs, theBox);
+    return aSegs;
+  }
+
+  //! Create primitive array with line segments for displaying a box.
+  //! @param theSegments [in] [out] primitive array to be filled;
+  //!                               should be at least 8 nodes and 24 edges in size
+  //! @param theBox [in] the box to add
+  static void FillSegments (const Handle(Graphic3d_ArrayOfSegments)& theSegments, const Bnd_OBB& theBox)
+  {
+    if (!theBox.IsVoid())
+    {
+      gp_Pnt aXYZ[8];
+      theBox.GetVertex (aXYZ);
+      fillSegments (theSegments, aXYZ);
+    }
+  }
+
+  //! Create primitive array with line segments for displaying a box.
+  //! @param theSegments [in] [out] primitive array to be filled;
+  //!                               should be at least 8 nodes and 24 edges in size
+  //! @param theBox [in] the box to add
+  static void FillSegments (const Handle(Graphic3d_ArrayOfSegments)& theSegments, const Bnd_Box& theBox)
+  {
+    if (!theBox.IsVoid())
+    {
+      const gp_Pnt aMin = theBox.CornerMin();
+      const gp_Pnt aMax = theBox.CornerMax();
+      const gp_Pnt aXYZ[8] =
+      {
+        gp_Pnt (aMin.X(), aMin.Y(), aMin.Z()),
+        gp_Pnt (aMax.X(), aMin.Y(), aMin.Z()),
+        gp_Pnt (aMin.X(), aMax.Y(), aMin.Z()),
+        gp_Pnt (aMax.X(), aMax.Y(), aMin.Z()),
+        gp_Pnt (aMin.X(), aMin.Y(), aMax.Z()),
+        gp_Pnt (aMax.X(), aMin.Y(), aMax.Z()),
+        gp_Pnt (aMin.X(), aMax.Y(), aMax.Z()),
+        gp_Pnt (aMax.X(), aMax.Y(), aMax.Z()),
+      };
+      fillSegments (theSegments, aXYZ);
+    }
+  }
+
+public:
+
+  //! Create primitive array with line segments for displaying a box.
+  //! @param theSegments [in] [out] primitive array to be filled;
+  //!                               should be at least 8 nodes and 24 edges in size
+  //! @param theBox [in] the box to add
+  static void fillSegments (const Handle(Graphic3d_ArrayOfSegments)& theSegments, const gp_Pnt* theBox)
+  {
+    const Standard_Integer aFrom = theSegments->VertexNumber();
+    for (int aVertIter = 0; aVertIter < 8; ++aVertIter)
+    {
+      theSegments->AddVertex (theBox[aVertIter]);
+    }
+
+    theSegments->AddEdges (aFrom + 1, aFrom + 2);
+    theSegments->AddEdges (aFrom + 3, aFrom + 4);
+    theSegments->AddEdges (aFrom + 5, aFrom + 6);
+    theSegments->AddEdges (aFrom + 7, aFrom + 8);
+    //
+    theSegments->AddEdges (aFrom + 1, aFrom + 3);
+    theSegments->AddEdges (aFrom + 2, aFrom + 4);
+    theSegments->AddEdges (aFrom + 5, aFrom + 7);
+    theSegments->AddEdges (aFrom + 6, aFrom + 8);
+    //
+    theSegments->AddEdges (aFrom + 1, aFrom + 5);
+    theSegments->AddEdges (aFrom + 2, aFrom + 6);
+    theSegments->AddEdges (aFrom + 3, aFrom + 7);
+    theSegments->AddEdges (aFrom + 4, aFrom + 8);
+  }
+
 };
 
 #endif // _StdPrs_BndBox_H__