]> OCCT Git - occt.git/commitdiff
0032078: Visualization, Poly_Triangulation - add cached bounding box.
authorosa <osa@opencascade.com>
Fri, 22 Jan 2021 14:56:45 +0000 (17:56 +0300)
committerbugmaster <bugmaster@opencascade.com>
Wed, 27 Jan 2021 18:21:32 +0000 (21:21 +0300)
1) Add empty constructor for Poly_Triangulation(),
2) Add Poly_Triangulation::HasGeometry() method to check that triangulation has any geometry.
3) Add possibility to cache bounding box in Poly_Triangulation and use it later in case of empty triangulation.
4) Add Poly_Triangulation::MinMax() to extends input box with bounding box of triangulation.
5) Add Poly_Triangulation::UpdateCachedMinMax() to cache min - max range of this triangulation with bounding box of nodal data.
6) Add virtual Poly_Triangulation::computeBoundingBox() to calculate bounding box of nodal data.
7) Update BRepBndLib::Add/AddOptimal/AddOBB algorithms to check empty triangulation and use cached box in this case.
8) Update BRepGProp::roughBary/surfaceProperties/volumeProperties to skip empty triangulation.
9) Remove additional myBox from RWGltf_GltfLatePrimitiveArray and some hack to save this box as nodes of base Poly_Triangulation.
10) Cache min-max range from JT file during its parsing

src/BRepBndLib/BRepBndLib.cxx
src/BRepBndLib/BRepBndLib_1.cxx
src/BRepGProp/BRepGProp.cxx
src/BRepGProp/BRepGProp_MeshProps.cxx
src/Poly/Poly_Triangulation.cxx
src/Poly/Poly_Triangulation.hxx
src/RWGltf/RWGltf_GltfJsonParser.cxx
src/RWGltf/RWGltf_GltfLatePrimitiveArray.cxx
src/RWGltf/RWGltf_GltfLatePrimitiveArray.hxx

index 903a03735ef76ef39de98e3f8e6e728ec90fc327..6ed0dc72810f517892d03d1363f948d9cf909146 100644 (file)
@@ -88,16 +88,10 @@ void BRepBndLib::Add(const TopoDS_Shape& S, Bnd_Box& B, Standard_Boolean useTria
     const TopoDS_Face& F = TopoDS::Face(ex.Current());
     const Handle(Poly_Triangulation)& T = BRep_Tool::Triangulation(F, l);
     const Handle(Geom_Surface)& GS = BRep_Tool::Surface (F, aDummyLoc);
-    if ((useTriangulation || GS.IsNull()) && !T.IsNull())
+    if ((useTriangulation || GS.IsNull()) && !T.IsNull() && T->MinMax (B, l))
     {
-      nbNodes = T->NbNodes();
-      const TColgp_Array1OfPnt& Nodes = T->Nodes();
-      for (i = 1; i <= nbNodes; i++) {
-        if (l.IsIdentity()) B.Add(Nodes(i));
-        else B.Add(Nodes(i).Transformed(l));
-      }
       //       B.Enlarge(T->Deflection());
-      B.Enlarge(T->Deflection() + BRep_Tool::Tolerance(F));
+      B.Enlarge (T->Deflection() + BRep_Tool::Tolerance (F));
     } else
     {
       if (!GS.IsNull()) {
@@ -137,14 +131,14 @@ void BRepBndLib::Add(const TopoDS_Shape& S, Bnd_Box& B, Standard_Boolean useTria
   {
     const TopoDS_Edge& E = TopoDS::Edge(ex.Current());
     Handle(Poly_Polygon3D) P3d = BRep_Tool::Polygon3D(E, l);
-    if (!P3d.IsNull())
+    if (!P3d.IsNull() && P3d->NbNodes() > 0)
     {
       const TColgp_Array1OfPnt& Nodes = P3d->Nodes();
       nbNodes = P3d->NbNodes();
       for (i = 1; i <= nbNodes; i++)
       {
-        if (l.IsIdentity()) B.Add(Nodes(i));
-        else B.Add(Nodes(i).Transformed(l));
+        if (l.IsIdentity()) B.Add(Nodes[i]);
+        else B.Add(Nodes[i].Transformed(l));
       }
       //       B.Enlarge(P3d->Deflection());
       B.Enlarge(P3d->Deflection() + BRep_Tool::Tolerance(E));
@@ -152,15 +146,24 @@ void BRepBndLib::Add(const TopoDS_Shape& S, Bnd_Box& B, Standard_Boolean useTria
     else
     {
       BRep_Tool::PolygonOnTriangulation(E, Poly, T, l);
-      if (useTriangulation && !Poly.IsNull())
+      if (useTriangulation && !Poly.IsNull() && !T.IsNull() && T->NbNodes() > 0)
       {
         const TColStd_Array1OfInteger& Indices = Poly->Nodes();
         const TColgp_Array1OfPnt& Nodes = T->Nodes();
         nbNodes = Indices.Length();
-        for (i = 1; i <= nbNodes; i++)
+        if (l.IsIdentity())
         {
-          if (l.IsIdentity()) B.Add(Nodes(Indices(i)));
-          else B.Add(Nodes(Indices(i)).Transformed(l));
+          for (i = 1; i <= nbNodes; i++)
+          {
+            B.Add(Nodes(Indices[i]));
+          }
+        }
+        else
+        {
+          for (i = 1; i <= nbNodes; i++)
+          {
+            B.Add(Nodes(Indices[i]).Transformed(l));
+          }
         }
         //     B.Enlarge(T->Deflection());
         B.Enlarge(Poly->Deflection() + BRep_Tool::Tolerance(E));
@@ -237,20 +240,14 @@ void BRepBndLib::AddOptimal(const TopoDS_Shape& S, Bnd_Box& B,
     const TopoDS_Face& F = TopoDS::Face(ex.Current());
     T = BRep_Tool::Triangulation(F, l);
     Bnd_Box aLocBox;
-    if (useTriangulation && !T.IsNull())
+    if (useTriangulation && !T.IsNull() && T->MinMax (aLocBox, l))
     {
-      nbNodes = T->NbNodes();
-      const TColgp_Array1OfPnt& Nodes = T->Nodes();
-      for (i = 1; i <= nbNodes; i++) {
-        if (l.IsIdentity()) aLocBox.Add(Nodes(i));
-        else aLocBox.Add(Nodes(i).Transformed(l));
-      }
       //       B.Enlarge(T->Deflection());
       aLocBox.Enlarge(T->Deflection() + BRep_Tool::Tolerance(F));
       Standard_Real xmin, ymin, zmin, xmax, ymax, zmax;
       aLocBox.Get(xmin, ymin, zmin, xmax, ymax, zmax);
       B.Update(xmin, ymin, zmin, xmax, ymax, zmax);
-    } 
+    }
     else
     {
       const Handle(Geom_Surface)& GS = BRep_Tool::Surface(F, l);
@@ -326,14 +323,14 @@ void BRepBndLib::AddOptimal(const TopoDS_Shape& S, Bnd_Box& B,
     const TopoDS_Edge& E = TopoDS::Edge(ex.Current());
     Bnd_Box aLocBox;
     Handle(Poly_Polygon3D) P3d = BRep_Tool::Polygon3D(E, l);
-    if (useTriangulation && (!P3d.IsNull()))
+    if (useTriangulation && !P3d.IsNull() && P3d->NbNodes() > 0)
     {
       const TColgp_Array1OfPnt& Nodes = P3d->Nodes();
       nbNodes = P3d->NbNodes();
       for (i = 1; i <= nbNodes; i++)
       {
-        if (l.IsIdentity()) aLocBox.Add(Nodes(i));
-        else aLocBox.Add(Nodes(i).Transformed(l));
+        if (l.IsIdentity()) aLocBox.Add(Nodes[i]);
+        else aLocBox.Add(Nodes[i].Transformed(l));
       }
       Standard_Real Tol = useShapeTolerance?  BRep_Tool::Tolerance(E) : 0.;
       aLocBox.Enlarge(P3d->Deflection() + Tol);
@@ -341,15 +338,15 @@ void BRepBndLib::AddOptimal(const TopoDS_Shape& S, Bnd_Box& B,
     else
     {
       BRep_Tool::PolygonOnTriangulation(E, Poly, T, l);
-      if (useTriangulation && !Poly.IsNull())
+      if (useTriangulation && !Poly.IsNull() && !T.IsNull() && T->NbNodes() > 0)
       {
         const TColStd_Array1OfInteger& Indices = Poly->Nodes();
         const TColgp_Array1OfPnt& Nodes = T->Nodes();
         nbNodes = Indices.Length();
         for (i = 1; i <= nbNodes; i++)
         {
-          if (l.IsIdentity()) aLocBox.Add(Nodes(Indices(i)));
-          else aLocBox.Add(Nodes(Indices(i)).Transformed(l));
+          if (l.IsIdentity()) aLocBox.Add(Nodes(Indices[i]));
+          else aLocBox.Add(Nodes(Indices[i]).Transformed(l));
         }
         Standard_Real Tol = useShapeTolerance?  BRep_Tool::Tolerance(E) : 0.;
         aLocBox.Enlarge(Poly->Deflection() + Tol);
index b63c87681faacfba6e6244d4c2235b0a0a7f4c27..bc3d872280d9a913b75e80a1ed5c6f99bd83c937 100644 (file)
@@ -196,8 +196,8 @@ static Standard_Integer PointsForOBB(const TopoDS_Shape& theS,
     {
       if (thePts)
       {
-        const gp_Pnt aP = aLoc.IsIdentity() ? aNodesArr(i) :
-          aNodesArr(i).Transformed(aLoc);
+        const gp_Pnt aP = aLoc.IsIdentity() ? aNodesArr[i] :
+          aNodesArr[i].Transformed(aLoc);
         (*thePts)(aRetVal) = aP;
       }
 
@@ -239,8 +239,8 @@ static Standard_Integer PointsForOBB(const TopoDS_Shape& theS,
     {
       if (thePts)
       {
-        const gp_Pnt aP = aLoc.IsIdentity() ? aNodesArr(i) :
-          aNodesArr(i).Transformed(aLoc);
+        const gp_Pnt aP = aLoc.IsIdentity() ? aNodesArr[i] :
+          aNodesArr[i].Transformed(aLoc);
         (*thePts)(aRetVal) = aP;
       }
 
index 1e998422aeb083c058444dd874bd80a09e080b01..9aab6e6019b4ce372283a1f5ad4abf3a6b22ca90 100644 (file)
@@ -55,7 +55,7 @@ static gp_Pnt roughBaryCenter(const TopoDS_Shape& S){
       TopLoc_Location aLocDummy;
       const Handle(Poly_Triangulation)& aTri =
         BRep_Tool::Triangulation(TopoDS::Face(aF), aLocDummy);
-      if (!aTri.IsNull())
+      if (!aTri.IsNull() && aTri->NbNodes() > 0)
       {
         xyz = aTri->Node(1).XYZ();
         if (!aLocDummy.IsIdentity())
@@ -148,7 +148,7 @@ static Standard_Real surfaceProperties(const TopoDS_Shape& S, GProp_GProps& Prop
         NoSurf = Standard_True;
       }
       const Handle(Poly_Triangulation)& aTri = BRep_Tool::Triangulation(F, aLocDummy);
-      if (aTri.IsNull())
+      if (aTri.IsNull() || aTri->NbNodes() == 0 || aTri->NbTriangles() == 0)
       {
         NoTri = Standard_True;
       }
@@ -261,7 +261,7 @@ static Standard_Real volumeProperties(const TopoDS_Shape& S, GProp_GProps& Props
         NoSurf = Standard_True;
       }
       const Handle(Poly_Triangulation)& aTri = BRep_Tool::Triangulation(F, aLocDummy);
-      if (aTri.IsNull())
+      if (aTri.IsNull() || aTri->NbNodes() == 0 || aTri->NbTriangles() == 0)
       {
         NoTri = Standard_True;
       }
index 0fc8af88fea7bef513c7eeb0782f8e3446772d34..408208a6017efebf8ccec225da87684d5f7e8337 100644 (file)
@@ -165,6 +165,10 @@ void BRepGProp_MeshProps::Perform(const Handle(Poly_Triangulation)& theMesh,
                                   const TopLoc_Location& theLoc,
                                   const TopAbs_Orientation theOri)
 {
+  if (theMesh.IsNull() || theMesh->NbNodes() == 0 || theMesh->NbTriangles() == 0)
+  {
+    return;
+  }
   if (theLoc.IsIdentity())
   {
     Perform(theMesh->Nodes(), theMesh->Triangles(), theOri);
@@ -229,6 +233,10 @@ void BRepGProp_MeshProps::Perform(const TColgp_Array1OfPnt& theNodes,
                                    const Poly_Array1OfTriangle& theTriangles,
                                    const TopAbs_Orientation theOri)
 {
+  if (theNodes.IsEmpty() || theTriangles.IsEmpty())
+  {
+    return;
+  }
   //
   // Gauss points for barycentriche coordinates
   static const Standard_Real GPtsWg[] =
index a1d67cc3dcd8980de7ecd822b945b449aea53fb4..ae7ed0df2e73ad7ddfb9c703fad3d319ced2a3da 100644 (file)
 
 IMPLEMENT_STANDARD_RTTIEXT (Poly_Triangulation, Standard_Transient)
 
+//=======================================================================
+//function : Poly_Triangulation
+//purpose  : 
+//=======================================================================
+Poly_Triangulation::Poly_Triangulation()
+: myCachedMinMax (NULL),
+  myDeflection   (0)
+{
+}
+
 //=======================================================================
 //function : Poly_Triangulation
 //purpose  : 
@@ -32,9 +42,10 @@ IMPLEMENT_STANDARD_RTTIEXT (Poly_Triangulation, Standard_Transient)
 Poly_Triangulation::Poly_Triangulation(const Standard_Integer theNbNodes,
                                        const Standard_Integer theNbTriangles,
                                        const Standard_Boolean theHasUVNodes)
-: myDeflection(0),
-  myNodes     (1, theNbNodes),
-  myTriangles (1, theNbTriangles)
+: myCachedMinMax (NULL),
+  myDeflection   (0),
+  myNodes        (1, theNbNodes),
+  myTriangles    (1, theNbTriangles)
 {
   if (theHasUVNodes) myUVNodes = new TColgp_HArray1OfPnt2d(1, theNbNodes);
 }
@@ -67,9 +78,10 @@ Poly_Triangulation::Poly_Triangulation(const Standard_Integer theNbNodes,
 //=======================================================================
 Poly_Triangulation::Poly_Triangulation(const TColgp_Array1OfPnt&    theNodes,
                                        const Poly_Array1OfTriangle& theTriangles)
-: myDeflection(0),
-  myNodes     (1, theNodes.Length()),
-  myTriangles (1, theTriangles.Length())
+: myCachedMinMax (NULL),
+  myDeflection   (0),
+  myNodes        (1, theNodes.Length()),
+  myTriangles    (1, theTriangles.Length())
 {
   myNodes = theNodes;
   myTriangles = theTriangles;
@@ -83,9 +95,10 @@ Poly_Triangulation::Poly_Triangulation(const TColgp_Array1OfPnt&    theNodes,
 Poly_Triangulation::Poly_Triangulation(const TColgp_Array1OfPnt&    theNodes,
                                        const TColgp_Array1OfPnt2d&  theUVNodes,
                                        const Poly_Array1OfTriangle& theTriangles)
-: myDeflection(0),
-  myNodes     (1, theNodes.Length()),
-  myTriangles (1, theTriangles.Length())
+: myCachedMinMax (NULL),
+  myDeflection   (0),
+  myNodes        (1, theNodes.Length()),
+  myTriangles    (1, theTriangles.Length())
 {
   myNodes = theNodes;
   myTriangles = theTriangles;
@@ -93,6 +106,15 @@ Poly_Triangulation::Poly_Triangulation(const TColgp_Array1OfPnt&    theNodes,
   myUVNodes->ChangeArray1() = theUVNodes;
 }
 
+//=======================================================================
+//function : ~Poly_Triangulation
+//purpose  :
+//=======================================================================
+Poly_Triangulation::~Poly_Triangulation()
+{
+  delete myCachedMinMax;
+}
+
 //=======================================================================
 //function : Copy
 //purpose  : 
@@ -100,16 +122,7 @@ Poly_Triangulation::Poly_Triangulation(const TColgp_Array1OfPnt&    theNodes,
 
 Handle(Poly_Triangulation) Poly_Triangulation::Copy() const
 {
-  Handle(Poly_Triangulation) aCopy;
-  if (HasUVNodes())
-    aCopy = new Poly_Triangulation(Nodes(), UVNodes(), Triangles());
-  else
-    aCopy = new Poly_Triangulation(Nodes(), Triangles());
-  aCopy->Deflection(myDeflection);
-  if (HasNormals())
-    aCopy->myNormals = new TShort_HArray1OfShortReal(myNormals->Array1());
-
-  return aCopy;
+  return new Poly_Triangulation (this);
 }
 
 //=======================================================================
@@ -118,10 +131,12 @@ Handle(Poly_Triangulation) Poly_Triangulation::Copy() const
 //=======================================================================
 
 Poly_Triangulation::Poly_Triangulation (const Handle(Poly_Triangulation)& theTriangulation)
-: myDeflection ( theTriangulation->myDeflection ),
+: myCachedMinMax(NULL),
+  myDeflection(theTriangulation->myDeflection),
   myNodes(theTriangulation->Nodes()),
   myTriangles(theTriangulation->Triangles())
 {
+  SetCachedMinMax (theTriangulation->CachedMinMax());
   if (theTriangulation->HasUVNodes())
   {
     myUVNodes = new TColgp_HArray1OfPnt2d(theTriangulation->myUVNodes->Array1());
@@ -349,3 +364,94 @@ void Poly_Triangulation::DumpJson (Standard_OStream& theOStream, Standard_Intege
     OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myNormals->Size())
   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myTriangles.Size())
 }
+
+// =======================================================================
+// function : CachedMinMax
+// purpose  :
+// =======================================================================
+const Bnd_Box& Poly_Triangulation::CachedMinMax() const
+{
+  static const Bnd_Box anEmptyBox;
+  return (myCachedMinMax == NULL) ? anEmptyBox : *myCachedMinMax;
+}
+
+// =======================================================================
+// function : SetCachedMinMax
+// purpose  :
+// =======================================================================
+void Poly_Triangulation::SetCachedMinMax (const Bnd_Box& theBox)
+{
+  if (theBox.IsVoid())
+  {
+    unsetCachedMinMax();
+    return;
+  }
+  if (myCachedMinMax == NULL)
+  {
+    myCachedMinMax = new Bnd_Box();
+  }
+  *myCachedMinMax = theBox;
+}
+
+// =======================================================================
+// function : unsetCachedMinMax
+// purpose  :
+// =======================================================================
+void Poly_Triangulation::unsetCachedMinMax()
+{
+  if (myCachedMinMax != NULL)
+  {
+    delete myCachedMinMax;
+    myCachedMinMax = NULL;
+  }
+}
+
+// =======================================================================
+// function : MinMax
+// purpose  :
+// =======================================================================
+Standard_Boolean Poly_Triangulation::MinMax (Bnd_Box& theBox, const gp_Trsf& theTrsf, const bool theIsAccurate) const
+{
+  Bnd_Box aBox;
+  if (HasCachedMinMax() &&
+      (!HasGeometry() || !theIsAccurate ||
+       theTrsf.Form() == gp_Identity || theTrsf.Form() == gp_Translation ||
+       theTrsf.Form() == gp_PntMirror || theTrsf.Form() == gp_Scale))
+  {
+    aBox = myCachedMinMax->Transformed (theTrsf);
+  }
+  else
+  {
+    aBox = computeBoundingBox (theTrsf);
+  }
+  if (aBox.IsVoid())
+  {
+    return Standard_False;
+  }
+  theBox.Add (aBox);
+  return Standard_True;
+}
+
+// =======================================================================
+// function : computeBoundingBox
+// purpose  :
+// =======================================================================
+Bnd_Box Poly_Triangulation::computeBoundingBox (const gp_Trsf& theTrsf) const
+{
+  Bnd_Box aBox;
+  if (theTrsf.Form() == gp_Identity)
+  {
+    for (Standard_Integer aNodeIdx = 1; aNodeIdx <= NbNodes(); aNodeIdx++)
+    {
+      aBox.Add (myNodes[aNodeIdx]);
+    }
+  }
+  else
+  {
+    for (Standard_Integer aNodeIdx = 1; aNodeIdx <= NbNodes(); aNodeIdx++)
+    {
+      aBox.Add (myNodes[aNodeIdx].Transformed (theTrsf));
+    }
+  }
+  return aBox;
+}
index ad7bc9481eeb605766e39105dfb9c15cc1d6099b..8808209d1f4af60eecb63b52a5b8c723ac2e56b3 100644 (file)
@@ -17,6 +17,7 @@
 #ifndef _Poly_Triangulation_HeaderFile
 #define _Poly_Triangulation_HeaderFile
 
+#include <Bnd_Box.hxx>
 #include <Standard.hxx>
 #include <Standard_DefineHandle.hxx>
 #include <Standard_Real.hxx>
@@ -68,6 +69,9 @@ public:
 
   DEFINE_STANDARD_RTTIEXT(Poly_Triangulation, Standard_Transient)
 
+  //! Constructs an empty triangulation.
+  Standard_EXPORT Poly_Triangulation();
+
   //! Constructs a triangulation from a set of triangles. The
   //! triangulation is initialized without a triangle or a node, but capable of
   //! containing nbNodes nodes, and nbTriangles
@@ -101,6 +105,9 @@ public:
   //! constructed triangulation.
   Standard_EXPORT Poly_Triangulation(const TColgp_Array1OfPnt& Nodes, const TColgp_Array1OfPnt2d& UVNodes, const Poly_Array1OfTriangle& Triangles);
 
+  //! Destructor
+  Standard_EXPORT virtual ~Poly_Triangulation();
+
   //! Creates full copy of current triangulation
   Standard_EXPORT virtual Handle(Poly_Triangulation) Copy() const;
 
@@ -117,6 +124,9 @@ public:
   //! Deallocates the UV nodes.
   Standard_EXPORT void RemoveUVNodes();
 
+  //! Returns TRUE if triangulation has some geometry.
+  virtual Standard_Boolean HasGeometry() const { return !myNodes.IsEmpty() && !myTriangles.IsEmpty(); }
+
   //! Returns the number of nodes for this triangulation.
   Standard_Integer NbNodes() const { return myNodes.Length(); }
 
@@ -207,11 +217,54 @@ public:
   Standard_EXPORT void SetNormal (const Standard_Integer theIndex,
                                   const gp_Dir&          theNormal);
 
+  //! Returns cached min - max range of triangulation data,
+  //! which is VOID by default (e.g, no cached information).
+  Standard_EXPORT const Bnd_Box& CachedMinMax() const;
+
+  //! Sets a cached min - max range of this triangulation.
+  //! The bounding box should exactly match actual range of triangulation data
+  //! without a gap or transformation, or otherwise undefined behavior will be observed.
+  //! Passing a VOID range invalidates the cache.
+  Standard_EXPORT void SetCachedMinMax (const Bnd_Box& theBox);
+
+  //! Returns TRUE if there is some cached min - max range of this triangulation.
+  Standard_EXPORT Standard_Boolean HasCachedMinMax() const { return myCachedMinMax != NULL; }
+
+  //! Updates cached min - max range of this triangulation with bounding box of nodal data.
+  void UpdateCachedMinMax()
+  {
+    Bnd_Box aBox;
+    MinMax (aBox, gp_Trsf(), true);
+    SetCachedMinMax (aBox);
+  }
+
+  //! Extends the passed box with bounding box of this triangulation.
+  //! Uses cached min - max range when available and:
+  //! - input transformation theTrsf has no rotation part;
+  //! - theIsAccurate is set to FALSE;
+  //! - no triangulation data available (e.g. it is deferred and not loaded).
+  //! @param theBox [in] [out] bounding box to extend by this triangulation
+  //! @param theTrsf [in] optional transformation
+  //! @param theIsAccurate [in] when FALSE, allows using a cached min - max range of this triangulation
+  //!                           even for non-identity transformation.
+  //! @return FALSE if there is no any data to extend the passed box (no both triangulation and cached min - max range).
+  Standard_EXPORT Standard_Boolean MinMax (Bnd_Box& theBox, const gp_Trsf& theTrsf, const bool theIsAccurate = false) const;
+
   //! Dumps the content of me into the stream
   Standard_EXPORT virtual void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
 
 protected:
 
+  //! Clears cached min - max range saved previously.
+  Standard_EXPORT void unsetCachedMinMax();
+
+  //! Calculates bounding box of nodal data.
+  //! @param theTrsf [in] optional transformation.
+  Standard_EXPORT virtual Bnd_Box computeBoundingBox (const gp_Trsf& theTrsf) const;
+
+protected:
+
+  Bnd_Box*                           myCachedMinMax;
   Standard_Real                      myDeflection;
   TColgp_Array1OfPnt                 myNodes;
   Handle(TColgp_HArray1OfPnt2d)      myUVNodes;
index 60bd3bc03813e83f5649256874c2f2b7923db143..8ef379737d85ac21b551dfe816cedc4ae8fc67ad 100644 (file)
@@ -1617,8 +1617,16 @@ bool RWGltf_GltfJsonParser::gltfParseAccessor (const Handle(RWGltf_GltfLatePrimi
             isValidMinMax = false;
             break;
           }
-          aMinPnt.SetCoord (anIter + 1, aMinVal.GetDouble());
-          aMinPnt.SetCoord (anIter + 1, aMaxVal.GetDouble());
+          double aMinDVal = aMinVal.GetDouble();
+          double aMaxDVal = aMaxVal.GetDouble();
+          if (aMinDVal > aMaxDVal)
+          {
+            reportGltfWarning ("Accessor '" + theName + "' defines invalid min/max value.");
+            isValidMinMax = false;
+            break;
+          }
+          aMinPnt.SetCoord (anIter + 1, aMinDVal);
+          aMaxPnt.SetCoord (anIter + 1, aMaxDVal);
         }
         if (isValidMinMax)
         {
@@ -1629,7 +1637,7 @@ bool RWGltf_GltfJsonParser::gltfParseAccessor (const Handle(RWGltf_GltfLatePrimi
           aBox.Add (aMinPnt);
           aBox.Add (aMaxPnt);
 
-          theMeshData->SetBoundingBox (aBox);
+          theMeshData->SetCachedMinMax (aBox);
         }
       }
     }
index fa486dac640aea3d0bebe3ae953da0954ca9b344..a76fa77315d6b107bf09eb57f8fc7206fd17ef95 100644 (file)
@@ -32,12 +32,11 @@ IMPLEMENT_STANDARD_RTTIEXT(RWGltf_GltfLatePrimitiveArray, Poly_Triangulation)
 // =======================================================================
 RWGltf_GltfLatePrimitiveArray::RWGltf_GltfLatePrimitiveArray (const TCollection_AsciiString& theId,
                                                               const TCollection_AsciiString& theName)
-: Poly_Triangulation (3, 1, false),
+: Poly_Triangulation(),
   myId (theId),
   myName (theName),
   myPrimMode (RWGltf_GltfPrimitiveMode_UNKNOWN)
 {
-  SetBoundingBox (Bnd_Box());
 }
 
 // =======================================================================
@@ -98,36 +97,3 @@ RWGltf_GltfPrimArrayData& RWGltf_GltfLatePrimitiveArray::AddPrimArrayData (RWGlt
     return myData.ChangeLast();
   }
 }
-
-// =======================================================================
-// function : SetBoundingBox
-// purpose  :
-// =======================================================================
-void RWGltf_GltfLatePrimitiveArray::SetBoundingBox (const Bnd_Box& theBox)
-{
-  myBox = theBox;
-
-  if (theBox.IsVoid())
-  {
-    Poly_Triangulation::myNodes = TColgp_Array1OfPnt();
-    Poly_Triangulation::myTriangles = Poly_Array1OfTriangle();
-    return;
-  }
-
-  // define 8 nodes so that AABB will be huge enough to include mesh even with transformation applied
-  Poly_Triangulation::myNodes.Resize (1, 8, false);
-  const gp_Pnt aMin = theBox.CornerMin();
-  const gp_Pnt aMax = theBox.CornerMax();
-  Poly_Triangulation::ChangeNode(1).SetCoord(aMin.X(), aMin.Y(), aMin.Z());
-  Poly_Triangulation::ChangeNode(2).SetCoord(aMax.X(), aMax.Y(), aMax.Z());
-  Poly_Triangulation::ChangeNode(3).SetCoord(aMin.X(), aMin.Y(), aMax.Z());
-  Poly_Triangulation::ChangeNode(4).SetCoord(aMin.X(), aMax.Y(), aMax.Z());
-  Poly_Triangulation::ChangeNode(5).SetCoord(aMax.X(), aMax.Y(), aMin.Z());
-  Poly_Triangulation::ChangeNode(6).SetCoord(aMax.X(), aMin.Y(), aMin.Z());
-  Poly_Triangulation::ChangeNode(7).SetCoord(aMin.X(), aMax.Y(), aMin.Z());
-  Poly_Triangulation::ChangeNode(8).SetCoord(aMax.X(), aMin.Y(), aMax.Z());
-
-  Poly_Triangulation::myTriangles.Resize (1, 1, false);
-  Poly_Triangulation::ChangeTriangle (1).Set (1, 2, 1);
-  //Poly_Triangulation::myTriangles = Poly_Array1OfTriangle();
-}
index 595ddb99572eb10eafac20589aea40e3c70241cc..ecc50324204f18f8625db701e58db76075394493 100644 (file)
@@ -15,7 +15,6 @@
 #ifndef _RWGltf_GltfLatePrimitiveArray_HeaderFile
 #define _RWGltf_GltfLatePrimitiveArray_HeaderFile
 
-#include <Bnd_Box.hxx>
 #include <NCollection_Sequence.hxx>
 #include <Poly_Triangulation.hxx>
 #include <RWGltf_GltfPrimArrayData.hxx>
@@ -79,20 +78,11 @@ public:
   //! Add primitive array data element.
   Standard_EXPORT RWGltf_GltfPrimArrayData& AddPrimArrayData (RWGltf_GltfArrayType theType);
 
-  //! Return bounding box defined within glTF file, or VOID if not specified.
-  const Bnd_Box& BoundingBox() const { return myBox; }
-
-  //! This method sets input bounding box and assigns a FAKE data to underlying Poly_Triangulation
-  //! as Min/Max corners of bounding box, so that standard tools like BRepBndLib::Add()
-  //! can be used transparently for computing bounding box of this face.
-  Standard_EXPORT void SetBoundingBox (const Bnd_Box& theBox);
-
 protected:
 
   NCollection_Sequence<RWGltf_GltfPrimArrayData> myData;
   Handle(RWGltf_MaterialMetallicRoughness) myMaterialPbr;    //!< PBR material
   Handle(RWGltf_MaterialCommon)            myMaterialCommon; //!< common (obsolete) material
-  Bnd_Box                  myBox;        //!< bounding box
   TCollection_AsciiString  myId;         //!< entity id
   TCollection_AsciiString  myName;       //!< entity name
   RWGltf_GltfPrimitiveMode myPrimMode;   //!< type of primitive array