IMPLEMENT_STANDARD_RTTIEXT (Poly_Triangulation, Standard_Transient)
+//=======================================================================
+//function : Poly_Triangulation
+//purpose :
+//=======================================================================
+Poly_Triangulation::Poly_Triangulation()
+: myCachedMinMax (NULL),
+ myDeflection (0)
+{
+}
+
//=======================================================================
//function : Poly_Triangulation
//purpose :
Poly_Triangulation::Poly_Triangulation(const Standard_Integer theNbNodes,
const Standard_Integer theNbTriangles,
const Standard_Boolean theHasUVNodes)
+: myCachedMinMax (NULL),
+ myDeflection (0),
+ myNodes (1, theNbNodes),
+ myTriangles (1, theNbTriangles)
+{
+ if (theHasUVNodes) myUVNodes = new TColgp_HArray1OfPnt2d(1, theNbNodes);
+}
+
+//=======================================================================
+//function : Poly_Triangulation
+//purpose :
+//=======================================================================
+Poly_Triangulation::Poly_Triangulation(const Standard_Integer theNbNodes,
+ const Standard_Integer theNbTriangles,
+ const Standard_Boolean theHasUVNodes,
+ const Standard_Boolean theHasNormals)
: myDeflection(0),
myNodes (1, theNbNodes),
myTriangles (1, theNbTriangles)
{
- if (theHasUVNodes) myUVNodes = new TColgp_HArray1OfPnt2d(1, theNbNodes);
+ if (theHasUVNodes)
+ {
+ myUVNodes = new TColgp_HArray1OfPnt2d(1, theNbNodes);
+ }
+ if (theHasNormals)
+ {
+ myNormals = new TShort_HArray1OfShortReal(1, theNbNodes * 3);
+ }
}
//=======================================================================
//function : Poly_Triangulation
-//purpose :
+//purpose :
//=======================================================================
-
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;
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;
myUVNodes->ChangeArray1() = theUVNodes;
}
+//=======================================================================
+//function : ~Poly_Triangulation
+//purpose :
+//=======================================================================
+Poly_Triangulation::~Poly_Triangulation()
+{
+ delete myCachedMinMax;
+}
+
//=======================================================================
//function : Copy
//purpose :
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);
}
//=======================================================================
//=======================================================================
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());
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;
+}
#ifndef _Poly_Triangulation_HeaderFile
#define _Poly_Triangulation_HeaderFile
+#include <Bnd_Box.hxx>
#include <Standard.hxx>
#include <Standard_DefineHandle.hxx>
#include <Standard_Real.hxx>
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
//! enable a 2D representation).
Standard_EXPORT Poly_Triangulation(const Standard_Integer nbNodes, const Standard_Integer nbTriangles, const Standard_Boolean UVNodes);
+ //! 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 triangles.
+ //! Here the UVNodes flag indicates whether 2D nodes will be associated with 3D ones,
+ //! (i.e. to enable a 2D representation).
+ //! Here the hasNormals flag indicates whether normals will be given and associated with nodes.
+ Standard_EXPORT Poly_Triangulation(const Standard_Integer nbNodes,
+ const Standard_Integer nbTriangles,
+ const Standard_Boolean UVNodes,
+ const Standard_Boolean hasNormals);
+
//! Constructs a triangulation from a set of triangles. The
//! triangulation is initialized with 3D points from Nodes and triangles
//! from Triangles.
//! 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;
//! 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(); }
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;