NCollection_AccAllocator.cxx
NCollection_AccAllocator.hxx
+NCollection_AliasedArray.hxx
NCollection_AlignedAllocator.cxx
NCollection_AlignedAllocator.hxx
NCollection_Array1.hxx
--- /dev/null
+// Copyright (c) 2021 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _NCollection_AliasedArray_HeaderFile
+#define _NCollection_AliasedArray_HeaderFile
+
+#include <NCollection_DefineAlloc.hxx>
+#include <NCollection_StlIterator.hxx>
+#include <Standard_DimensionMismatch.hxx>
+#include <Standard_OutOfMemory.hxx>
+#include <Standard_OutOfRange.hxx>
+#include <Standard_TypeMismatch.hxx>
+
+//! Defines an array of values of configurable size.
+//! For instance, this class allows defining an array of 32-bit or 64-bit integer values with bitness determined in runtime.
+//! The element size in bytes (stride) should be specified at construction time.
+//! Indexation starts from 0 index.
+//! As actual type of element varies at runtime, element accessors are defined as templates.
+//! Memory for array is allocated with the given alignment (template parameter).
+template<int MyAlignSize = 16>
+class NCollection_AliasedArray
+{
+public:
+ DEFINE_STANDARD_ALLOC
+public:
+
+ //! Empty constructor.
+ NCollection_AliasedArray (Standard_Integer theStride)
+ : myData (NULL), myStride (theStride), mySize (0), myDeletable (false)
+ {
+ if (theStride <= 0) { throw Standard_RangeError ("NCollection_AliasedArray, stride should be positive"); }
+ }
+
+ //! Constructor
+ NCollection_AliasedArray (Standard_Integer theStride,
+ Standard_Integer theLength)
+ : myData (NULL), myStride (theStride), mySize (theLength), myDeletable (true)
+ {
+ if (theLength <= 0 || myStride <= 0) { throw Standard_RangeError ("NCollection_AliasedArray, stride and length should be positive"); }
+ myData = (Standard_Byte* )Standard::AllocateAligned (SizeBytes(), MyAlignSize);
+ if (myData == NULL) { throw Standard_OutOfMemory ("NCollection_AliasedArray, allocation failed"); }
+ }
+
+ //! Copy constructor
+ NCollection_AliasedArray (const NCollection_AliasedArray& theOther)
+ : myData (NULL), myStride (theOther.myStride), mySize (theOther.mySize), myDeletable (false)
+ {
+ if (mySize != 0)
+ {
+ myDeletable = true;
+ myData = (Standard_Byte* )Standard::AllocateAligned (SizeBytes(), MyAlignSize);
+ if (myData == NULL) { throw Standard_OutOfMemory ("NCollection_AliasedArray, allocation failed"); }
+ Assign (theOther);
+ }
+ }
+
+#ifndef OCCT_NO_RVALUE_REFERENCE
+ //! Move constructor
+ NCollection_AliasedArray (NCollection_AliasedArray&& theOther)
+ : myData (theOther.myData), myStride (theOther.myStride), mySize (theOther.mySize), myDeletable (theOther.myDeletable)
+ {
+ theOther.myDeletable = false;
+ }
+#endif
+
+ //! Constructor wrapping pre-allocated C-array of values without copying them.
+ template<typename Type_t>
+ NCollection_AliasedArray (const Type_t& theBegin,
+ Standard_Integer theLength)
+ : myData ((Standard_Byte* )&theBegin), myStride ((int )sizeof(Type_t)), mySize (theLength), myDeletable (false)
+ {
+ if (theLength <= 0) { throw Standard_RangeError ("NCollection_AliasedArray, length should be positive"); }
+ }
+
+ //! Returns an element size in bytes.
+ Standard_Integer Stride() const { return myStride; }
+
+ //! Size query
+ Standard_Integer Size() const { return mySize; }
+
+ //! Length query (the same as Size())
+ Standard_Integer Length() const { return mySize; }
+
+ //! Return TRUE if array has zero length.
+ Standard_Boolean IsEmpty() const { return mySize == 0; }
+
+ //! Lower bound
+ Standard_Integer Lower() const { return 0; }
+
+ //! Upper bound
+ Standard_Integer Upper() const { return mySize - 1; }
+
+ //! myDeletable flag
+ Standard_Boolean IsDeletable() const { return myDeletable; }
+
+ //! IsAllocated flag - for naming compatibility
+ Standard_Boolean IsAllocated() const { return myDeletable; }
+
+ //! Return buffer size in bytes.
+ Standard_Size SizeBytes() const { return size_t(myStride) * size_t(mySize); }
+
+ //! Copies data of theOther array to this.
+ //! This array should be pre-allocated and have the same length as theOther;
+ //! otherwise exception Standard_DimensionMismatch is thrown.
+ NCollection_AliasedArray& Assign (const NCollection_AliasedArray& theOther)
+ {
+ if (&theOther != this)
+ {
+ if (myStride != theOther.myStride || mySize != theOther.mySize)
+ {
+ throw Standard_DimensionMismatch ("NCollection_AliasedArray::Assign(), arrays have different size");
+ }
+ if (myData != NULL)
+ {
+ memcpy (myData, theOther.myData, SizeBytes());
+ }
+ }
+ return *this;
+ }
+
+ //! Move assignment.
+ //! This array will borrow all the data from theOther.
+ //! The moved object will keep pointer to the memory buffer and
+ //! range, but it will not free the buffer on destruction.
+ NCollection_AliasedArray& Move (NCollection_AliasedArray& theOther)
+ {
+ if (&theOther != this)
+ {
+ if (myDeletable)
+ {
+ Standard::FreeAligned (myData);
+ }
+ myStride = theOther.myStride;
+ mySize = theOther.mySize;
+ myDeletable = theOther.myDeletable;
+ myData = theOther.myData;
+ theOther.myDeletable = false;
+ }
+ return *this;
+ }
+
+ //! Assignment operator; @sa Assign()
+ NCollection_AliasedArray& operator= (const NCollection_AliasedArray& theOther)
+ {
+ return Assign (theOther);
+ }
+
+#ifndef OCCT_NO_RVALUE_REFERENCE
+ //! Move assignment operator; @sa Move()
+ NCollection_AliasedArray& operator= (NCollection_AliasedArray&& theOther)
+ {
+ return Move (theOther);
+ }
+#endif
+
+ //! Resizes the array to specified bounds.
+ //! No re-allocation will be done if length of array does not change,
+ //! but existing values will not be discarded if theToCopyData set to FALSE.
+ //! @param theLength new length of array
+ //! @param theToCopyData flag to copy existing data into new array
+ void Resize (Standard_Integer theLength,
+ Standard_Boolean theToCopyData)
+ {
+ if (theLength <= 0) { throw Standard_RangeError ("NCollection_AliasedArray::Resize, length should be positive"); }
+ if (mySize == theLength)
+ {
+ return;
+ }
+
+ const Standard_Integer anOldLen = mySize;
+ const Standard_Byte* anOldData = myData;
+ mySize = theLength;
+ if (!theToCopyData && myDeletable)
+ {
+ Standard::FreeAligned (myData);
+ }
+ myData = (Standard_Byte* )Standard::AllocateAligned (SizeBytes(), MyAlignSize);
+ if (myData == NULL) { throw Standard_OutOfMemory ("NCollection_AliasedArray, allocation failed"); }
+ if (!theToCopyData)
+ {
+ myDeletable = true;
+ return;
+ }
+
+ const size_t aLenCopy = size_t(Min (anOldLen, theLength)) * size_t(myStride);
+ memcpy (myData, anOldData, aLenCopy);
+ if (myDeletable)
+ {
+ Standard::FreeAligned (anOldData);
+ }
+ myDeletable = true;
+ }
+
+ //! Destructor - releases the memory
+ ~NCollection_AliasedArray()
+ {
+ if (myDeletable)
+ {
+ Standard::FreeAligned (myData);
+ }
+ }
+
+public:
+
+ //! Access raw bytes of specified element.
+ const Standard_Byte* value (Standard_Integer theIndex) const
+ {
+ Standard_OutOfRange_Raise_if (theIndex < 0 || theIndex >= mySize, "NCollection_AliasedArray::value(), out of range index");
+ return myData + size_t(myStride) * size_t(theIndex);
+ }
+
+ //! Access raw bytes of specified element.
+ Standard_Byte* changeValue (Standard_Integer theIndex)
+ {
+ Standard_OutOfRange_Raise_if (theIndex < 0 || theIndex >= mySize, "NCollection_AliasedArray::changeValue(), out of range index");
+ return myData + size_t(myStride) * size_t(theIndex);
+ }
+
+ //! Initialize the items with theValue
+ template<typename Type_t> void Init (const Type_t& theValue)
+ {
+ for (Standard_Integer anIter = 0; anIter < mySize; ++anIter)
+ {
+ ChangeValue<Type_t> (anIter) = theValue;
+ }
+ }
+
+ //! Access element with specified position and type.
+ //! This method requires size of a type matching stride value.
+ template<typename Type_t> const Type_t& Value (Standard_Integer theIndex) const
+ {
+ Standard_TypeMismatch_Raise_if(size_t(myStride) != sizeof(Type_t), "NCollection_AliasedArray::Value(), wrong type");
+ return *reinterpret_cast<const Type_t*>(value (theIndex));
+ }
+
+ //! Access element with specified position and type.
+ //! This method requires size of a type matching stride value.
+ template<typename Type_t> void Value (Standard_Integer theIndex, Type_t& theValue) const
+ {
+ Standard_TypeMismatch_Raise_if(size_t(myStride) != sizeof(Type_t), "NCollection_AliasedArray::Value(), wrong type");
+ theValue = *reinterpret_cast<const Type_t*>(value (theIndex));
+ }
+
+ //! Access element with specified position and type.
+ //! This method requires size of a type matching stride value.
+ template<typename Type_t> Type_t& ChangeValue (Standard_Integer theIndex)
+ {
+ Standard_TypeMismatch_Raise_if(size_t(myStride) != sizeof(Type_t), "NCollection_AliasedArray::ChangeValue(), wrong type");
+ return *reinterpret_cast<Type_t* >(changeValue (theIndex));
+ }
+
+ //! Access element with specified position and type.
+ //! This method allows wrapping element into smaller type (e.g. to alias 2-components within 3-component vector).
+ template<typename Type_t> const Type_t& Value2 (Standard_Integer theIndex) const
+ {
+ Standard_TypeMismatch_Raise_if(size_t(myStride) < sizeof(Type_t), "NCollection_AliasedArray::Value2(), wrong type");
+ return *reinterpret_cast<const Type_t*>(value (theIndex));
+ }
+
+ //! Access element with specified position and type.
+ //! This method allows wrapping element into smaller type (e.g. to alias 2-components within 3-component vector).
+ template<typename Type_t> void Value2 (Standard_Integer theIndex, Type_t& theValue) const
+ {
+ Standard_TypeMismatch_Raise_if(size_t(myStride) < sizeof(Type_t), "NCollection_AliasedArray::Value2(), wrong type");
+ theValue = *reinterpret_cast<const Type_t*>(value (theIndex));
+ }
+
+ //! Access element with specified position and type.
+ //! This method allows wrapping element into smaller type (e.g. to alias 2-components within 3-component vector).
+ template<typename Type_t>
+ Type_t& ChangeValue2 (Standard_Integer theIndex)
+ {
+ Standard_TypeMismatch_Raise_if(size_t(myStride) < sizeof(Type_t), "NCollection_AliasedArray::ChangeValue2(), wrong type");
+ return *reinterpret_cast<Type_t* >(changeValue (theIndex));
+ }
+
+ //! Return first element
+ template<typename Type_t> const Type_t& First() const { return Value<Type_t> (0); }
+
+ //! Return first element
+ template<typename Type_t> Type_t& ChangeFirst() { return ChangeValue<Type_t> (0); }
+
+ //! Return last element
+ template<typename Type_t> const Type_t& Last() const { return Value<Type_t> (mySize - 1); }
+
+ //! Return last element
+ template<typename Type_t> Type_t& ChangeLast() { return Value<Type_t> (mySize - 1); }
+
+protected:
+
+ Standard_Byte* myData; //!< data pointer
+ Standard_Integer myStride; //!< element size
+ Standard_Integer mySize; //!< number of elements
+ Standard_Boolean myDeletable; //!< flag showing who allocated the array
+
+};
+
+#endif // _NCollection_AliasedArray_HeaderFile
Poly.cxx
Poly.hxx
Poly_Array1OfTriangle.hxx
+Poly_ArrayOfNodes.cxx
+Poly_ArrayOfNodes.hxx
+Poly_ArrayOfUVNodes.cxx
+Poly_ArrayOfUVNodes.hxx
Poly_CoherentLink.cxx
Poly_CoherentLink.hxx
Poly_CoherentNode.cxx
--- /dev/null
+// Copyright (c) 2021 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Poly_ArrayOfNodes.hxx>
+
+// =======================================================================
+// function : Poly_ArrayOfNodes
+// purpose :
+// =======================================================================
+Poly_ArrayOfNodes::Poly_ArrayOfNodes (const Poly_ArrayOfNodes& theOther)
+: NCollection_AliasedArray (theOther)
+{
+ //
+}
+
+// =======================================================================
+// function : ~Poly_ArrayOfNodes
+// purpose :
+// =======================================================================
+Poly_ArrayOfNodes::~Poly_ArrayOfNodes()
+{
+ //
+}
+
+// =======================================================================
+// function : Assign
+// purpose :
+// =======================================================================
+Poly_ArrayOfNodes& Poly_ArrayOfNodes::Assign (const Poly_ArrayOfNodes& theOther)
+{
+ if (&theOther == this)
+ {
+ return *this;
+ }
+
+ if (myStride == theOther.myStride)
+ {
+ // fast copy
+ NCollection_AliasedArray::Assign (theOther);
+ return *this;
+ }
+
+ // slow copy
+ if (mySize != theOther.mySize) { throw Standard_DimensionMismatch ("Poly_ArrayOfNodes::Assign(), arrays have different sizes"); }
+ for (int anIter = 0; anIter < mySize; ++anIter)
+ {
+ const gp_Pnt aPnt = theOther.Value (anIter);
+ SetValue (anIter, aPnt);
+ }
+ return *this;
+}
--- /dev/null
+// Copyright (c) 2021 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Poly_ArrayOfNodes_HeaderFile
+#define _Poly_ArrayOfNodes_HeaderFile
+
+#include <NCollection_AliasedArray.hxx>
+#include <gp_Pnt.hxx>
+#include <gp_Vec3f.hxx>
+
+//! Defines an array of 3D nodes of single/double precision configurable at construction time.
+class Poly_ArrayOfNodes : public NCollection_AliasedArray<>
+{
+public:
+
+ //! Empty constructor of double-precision array.
+ Poly_ArrayOfNodes() : NCollection_AliasedArray ((Standard_Integer )sizeof(gp_Pnt))
+ {
+ //
+ }
+
+ //! Constructor of double-precision array.
+ Poly_ArrayOfNodes (Standard_Integer theLength)
+ : NCollection_AliasedArray ((Standard_Integer )sizeof(gp_Pnt), theLength)
+ {
+ //
+ }
+
+ //! Copy constructor
+ Standard_EXPORT Poly_ArrayOfNodes (const Poly_ArrayOfNodes& theOther);
+
+ //! Constructor wrapping pre-allocated C-array of values without copying them.
+ Poly_ArrayOfNodes (const gp_Pnt& theBegin,
+ Standard_Integer theLength)
+ : NCollection_AliasedArray (theBegin, theLength)
+ {
+ //
+ }
+
+ //! Constructor wrapping pre-allocated C-array of values without copying them.
+ Poly_ArrayOfNodes (const gp_Vec3f& theBegin,
+ Standard_Integer theLength)
+ : NCollection_AliasedArray (theBegin, theLength)
+ {
+ //
+ }
+
+ //! Destructor.
+ Standard_EXPORT ~Poly_ArrayOfNodes();
+
+ //! Returns TRUE if array defines nodes with double precision.
+ bool IsDoublePrecision() const { return myStride == (Standard_Integer )sizeof(gp_Pnt); }
+
+ //! Sets if array should define nodes with double or single precision.
+ //! Raises exception if array was already allocated.
+ void SetDoublePrecision (bool theIsDouble)
+ {
+ if (myData != NULL) { throw Standard_ProgramError ("Poly_ArrayOfNodes::SetDoublePrecision() should be called before allocation"); }
+ myStride = Standard_Integer(theIsDouble ? sizeof(gp_Pnt) : sizeof(gp_Vec3f));
+ }
+
+ //! Copies data of theOther array to this.
+ //! The arrays should have the same length,
+ //! but may have different precision / number of components (data conversion will be applied in the latter case).
+ Standard_EXPORT Poly_ArrayOfNodes& Assign (const Poly_ArrayOfNodes& theOther);
+
+ //! Move assignment.
+ Poly_ArrayOfNodes& Move (Poly_ArrayOfNodes& theOther)
+ {
+ NCollection_AliasedArray::Move (theOther);
+ return *this;
+ }
+
+ //! Assignment operator; @sa Assign()
+ Poly_ArrayOfNodes& operator= (const Poly_ArrayOfNodes& theOther) { return Assign (theOther); }
+
+#ifndef OCCT_NO_RVALUE_REFERENCE
+ //! Move constructor
+ Poly_ArrayOfNodes (Poly_ArrayOfNodes&& theOther)
+ : NCollection_AliasedArray (std::move (theOther))
+ {
+ //
+ }
+
+ //! Move assignment operator; @sa Move()
+ Poly_ArrayOfNodes& operator= (Poly_ArrayOfNodes&& theOther)
+ {
+ return Move (theOther);
+ }
+#endif
+
+public:
+
+ //! A generalized accessor to point.
+ inline gp_Pnt Value (Standard_Integer theIndex) const;
+
+ //! A generalized setter for point.
+ inline void SetValue (Standard_Integer theIndex, const gp_Pnt& theValue);
+
+ //! operator[] - alias to Value
+ gp_Pnt operator[] (Standard_Integer theIndex) const { return Value (theIndex); }
+
+};
+
+// =======================================================================
+// function : Value
+// purpose :
+// =======================================================================
+inline gp_Pnt Poly_ArrayOfNodes::Value (Standard_Integer theIndex) const
+{
+ if (myStride == (Standard_Integer )sizeof(gp_Pnt))
+ {
+ return NCollection_AliasedArray::Value<gp_Pnt> (theIndex);
+ }
+ else
+ {
+ const gp_Vec3f& aVec3 = NCollection_AliasedArray::Value<gp_Vec3f> (theIndex);
+ return gp_Pnt (aVec3.x(), aVec3.y(), aVec3.z());
+ }
+}
+
+// =======================================================================
+// function : SetValue
+// purpose :
+// =======================================================================
+inline void Poly_ArrayOfNodes::SetValue (Standard_Integer theIndex, const gp_Pnt& theValue)
+{
+ if (myStride == (Standard_Integer )sizeof(gp_Pnt))
+ {
+ NCollection_AliasedArray::ChangeValue<gp_Pnt> (theIndex) = theValue;
+ }
+ else
+ {
+ gp_Vec3f& aVec3 = NCollection_AliasedArray::ChangeValue<gp_Vec3f> (theIndex);
+ aVec3.SetValues ((float )theValue.X(), (float )theValue.Y(), (float )theValue.Z());
+ }
+}
+
+#endif // _Poly_ArrayOfNodes_HeaderFile
--- /dev/null
+// Copyright (c) 2021 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Poly_ArrayOfUVNodes.hxx>
+
+// =======================================================================
+// function : Poly_ArrayOfUVNodes
+// purpose :
+// =======================================================================
+Poly_ArrayOfUVNodes::Poly_ArrayOfUVNodes (const Poly_ArrayOfUVNodes& theOther)
+: NCollection_AliasedArray (theOther)
+{
+ //
+}
+
+// =======================================================================
+// function : ~Poly_ArrayOfUVNodes
+// purpose :
+// =======================================================================
+Poly_ArrayOfUVNodes::~Poly_ArrayOfUVNodes()
+{
+ //
+}
+
+// =======================================================================
+// function : Assign
+// purpose :
+// =======================================================================
+Poly_ArrayOfUVNodes& Poly_ArrayOfUVNodes::Assign (const Poly_ArrayOfUVNodes& theOther)
+{
+ if (&theOther == this)
+ {
+ return *this;
+ }
+
+ if (myStride == theOther.myStride)
+ {
+ // fast copy
+ NCollection_AliasedArray::Assign (theOther);
+ return *this;
+ }
+
+ // slow copy
+ if (mySize != theOther.mySize) { throw Standard_DimensionMismatch ("Poly_ArrayOfUVNodes::Assign(), arrays have different sizes"); }
+ for (int anIter = 0; anIter < mySize; ++anIter)
+ {
+ const gp_Pnt2d aPnt = theOther.Value (anIter);
+ SetValue (anIter, aPnt);
+ }
+ return *this;
+}
--- /dev/null
+// Copyright (c) 2021 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _Poly_ArrayOfUVNodes_HeaderFile
+#define _Poly_ArrayOfUVNodes_HeaderFile
+
+#include <NCollection_AliasedArray.hxx>
+#include <gp_Pnt2d.hxx>
+#include <gp_Vec2f.hxx>
+
+//! Defines an array of 2D nodes of single/double precision configurable at construction time.
+class Poly_ArrayOfUVNodes : public NCollection_AliasedArray<>
+{
+public:
+
+ //! Empty constructor of double-precision array.
+ Poly_ArrayOfUVNodes() : NCollection_AliasedArray ((Standard_Integer )sizeof(gp_Pnt2d))
+ {
+ //
+ }
+
+ //! Constructor of double-precision array.
+ Poly_ArrayOfUVNodes (Standard_Integer theLength)
+ : NCollection_AliasedArray ((Standard_Integer )sizeof(gp_Pnt2d), theLength)
+ {
+ //
+ }
+
+ //! Copy constructor
+ Standard_EXPORT Poly_ArrayOfUVNodes (const Poly_ArrayOfUVNodes& theOther);
+
+ //! Constructor wrapping pre-allocated C-array of values without copying them.
+ Poly_ArrayOfUVNodes (const gp_Pnt2d& theBegin,
+ Standard_Integer theLength)
+ : NCollection_AliasedArray (theBegin, theLength)
+ {
+ //
+ }
+
+ //! Constructor wrapping pre-allocated C-array of values without copying them.
+ Poly_ArrayOfUVNodes (const gp_Vec2f& theBegin,
+ Standard_Integer theLength)
+ : NCollection_AliasedArray (theBegin, theLength)
+ {
+ //
+ }
+
+ //! Destructor.
+ Standard_EXPORT ~Poly_ArrayOfUVNodes();
+
+ //! Returns TRUE if array defines nodes with double precision.
+ bool IsDoublePrecision() const { return myStride == (Standard_Integer )sizeof(gp_Pnt2d); }
+
+ //! Sets if array should define nodes with double or single precision.
+ //! Raises exception if array was already allocated.
+ void SetDoublePrecision (bool theIsDouble)
+ {
+ if (myData != NULL) { throw Standard_ProgramError ("Poly_ArrayOfUVNodes::SetDoublePrecision() should be called before allocation"); }
+ myStride = Standard_Integer(theIsDouble ? sizeof(gp_Pnt2d) : sizeof(gp_Vec2f));
+ }
+
+ //! Copies data of theOther array to this.
+ //! The arrays should have the same length,
+ //! but may have different precision / number of components (data conversion will be applied in the latter case).
+ Standard_EXPORT Poly_ArrayOfUVNodes& Assign (const Poly_ArrayOfUVNodes& theOther);
+
+ //! Move assignment.
+ Poly_ArrayOfUVNodes& Move (Poly_ArrayOfUVNodes& theOther)
+ {
+ NCollection_AliasedArray::Move (theOther);
+ return *this;
+ }
+
+ //! Assignment operator; @sa Assign()
+ Poly_ArrayOfUVNodes& operator= (const Poly_ArrayOfUVNodes& theOther) { return Assign (theOther); }
+
+#ifndef OCCT_NO_RVALUE_REFERENCE
+ //! Move constructor
+ Poly_ArrayOfUVNodes (Poly_ArrayOfUVNodes&& theOther)
+ : NCollection_AliasedArray (std::move (theOther))
+ {
+ //
+ }
+
+ //! Move assignment operator; @sa Move()
+ Poly_ArrayOfUVNodes& operator= (Poly_ArrayOfUVNodes&& theOther)
+ {
+ return Move (theOther);
+ }
+#endif
+
+public:
+
+ //! A generalized accessor to point.
+ inline gp_Pnt2d Value (Standard_Integer theIndex) const;
+
+ //! A generalized setter for point.
+ inline void SetValue (Standard_Integer theIndex, const gp_Pnt2d& theValue);
+
+ //! operator[] - alias to Value
+ gp_Pnt2d operator[] (Standard_Integer theIndex) const { return Value (theIndex); }
+
+};
+
+// =======================================================================
+// function : Value
+// purpose :
+// =======================================================================
+inline gp_Pnt2d Poly_ArrayOfUVNodes::Value (Standard_Integer theIndex) const
+{
+ if (myStride == (Standard_Integer )sizeof(gp_Pnt2d))
+ {
+ return NCollection_AliasedArray::Value<gp_Pnt2d> (theIndex);
+ }
+ else
+ {
+ const gp_Vec2f& aVec2 = NCollection_AliasedArray::Value<gp_Vec2f> (theIndex);
+ return gp_Pnt2d (aVec2.x(), aVec2.y());
+ }
+}
+
+// =======================================================================
+// function : SetValue
+// purpose :
+// =======================================================================
+inline void Poly_ArrayOfUVNodes::SetValue (Standard_Integer theIndex, const gp_Pnt2d& theValue)
+{
+ if (myStride == (Standard_Integer )sizeof(gp_Pnt2d))
+ {
+ NCollection_AliasedArray::ChangeValue<gp_Pnt2d> (theIndex) = theValue;
+ }
+ else
+ {
+ gp_Vec2f& aVec2 = NCollection_AliasedArray::ChangeValue<gp_Vec2f> (theIndex);
+ aVec2.SetValues ((float )theValue.X(), (float )theValue.Y());
+ }
+}
+
+#endif // _Poly_ArrayOfUVNodes_HeaderFile
: myCachedMinMax (NULL),
myDeflection (0)
{
+ //
}
//=======================================================================
const Standard_Boolean theHasNormals)
: myCachedMinMax (NULL),
myDeflection(0),
- myNodes (1, theNbNodes),
+ myNodes (theNbNodes),
myTriangles (1, theNbTriangles)
{
if (theHasUVNodes)
{
- myUVNodes.Resize (1, theNbNodes, false);
+ myUVNodes.Resize (theNbNodes, false);
}
if (theHasNormals)
{
- myNormals.Resize (1, theNbNodes, false);
+ myNormals.Resize (0, theNbNodes - 1, false);
}
}
const Poly_Array1OfTriangle& theTriangles)
: myCachedMinMax (NULL),
myDeflection (0),
- myNodes (1, theNodes.Length()),
+ myNodes (theNodes.Length()),
myTriangles (1, theTriangles.Length())
{
- myNodes = theNodes;
+ const Poly_ArrayOfNodes aNodeWrapper (theNodes.First(), theNodes.Length());
+ myNodes = aNodeWrapper;
myTriangles = theTriangles;
}
const Poly_Array1OfTriangle& theTriangles)
: myCachedMinMax (NULL),
myDeflection (0),
- myNodes (1, theNodes.Length()),
+ myNodes (theNodes.Length()),
myTriangles (1, theTriangles.Length()),
- myUVNodes (1, theNodes.Length())
+ myUVNodes (theNodes.Length())
{
- myNodes = theNodes;
+ const Poly_ArrayOfNodes aNodeWrapper (theNodes.First(), theNodes.Length());
+ myNodes = aNodeWrapper;
myTriangles = theTriangles;
- myUVNodes = theUVNodes;
+ const Poly_ArrayOfUVNodes aUVNodeWrapper (theUVNodes.First(), theUVNodes.Length());
+ myUVNodes = aUVNodeWrapper;
}
//=======================================================================
{
if (!myUVNodes.IsEmpty())
{
- TColgp_Array1OfPnt2d anEmpty;
+ Poly_ArrayOfUVNodes anEmpty;
+ anEmpty.SetDoublePrecision (myUVNodes.IsDoublePrecision());
myUVNodes.Move (anEmpty);
}
}
return Handle(TColgp_HArray1OfPnt)();
}
- Handle(TColgp_HArray1OfPnt) anHArray = new TColgp_HArray1OfPnt();
- TColgp_Array1OfPnt anArray (myNodes.First(), 1, NbNodes());
- anHArray->Move (anArray);
- return anHArray;
+ if (myNodes.IsDoublePrecision())
+ {
+ // wrap array
+ const gp_Pnt* aPntArr = &myNodes.First<gp_Pnt>();
+ Handle(TColgp_HArray1OfPnt) anHArray = new TColgp_HArray1OfPnt();
+ TColgp_Array1OfPnt anArray (*aPntArr, 1, NbNodes());
+ anHArray->Move (anArray);
+ return anHArray;
+ }
+
+ // deep copy
+ Handle(TColgp_HArray1OfPnt) anArray = new TColgp_HArray1OfPnt (1, NbNodes());
+ for (Standard_Integer aNodeIter = 0; aNodeIter < NbNodes(); ++aNodeIter)
+ {
+ const gp_Pnt aPnt = myNodes.Value (aNodeIter);
+ anArray->SetValue (aNodeIter + 1, aPnt);
+ }
+ return anArray;
}
//=======================================================================
return Handle(TColgp_HArray1OfPnt2d)();
}
- Handle(TColgp_HArray1OfPnt2d) anHArray = new TColgp_HArray1OfPnt2d();
- TColgp_Array1OfPnt2d anArray (myUVNodes.First(), 1, NbNodes());
- anHArray->Move (anArray);
- return anHArray;
+ if (myUVNodes.IsDoublePrecision())
+ {
+ // wrap array
+ const gp_Pnt2d* aPntArr = &myUVNodes.First<gp_Pnt2d>();
+ Handle(TColgp_HArray1OfPnt2d) anHArray = new TColgp_HArray1OfPnt2d();
+ TColgp_Array1OfPnt2d anArray (*aPntArr, 1, NbNodes());
+ anHArray->Move (anArray);
+ return anHArray;
+ }
+
+ // deep copy
+ Handle(TColgp_HArray1OfPnt2d) anArray = new TColgp_HArray1OfPnt2d (1, NbNodes());
+ for (Standard_Integer aNodeIter = 0; aNodeIter < NbNodes(); ++aNodeIter)
+ {
+ const gp_Pnt2d aPnt = myUVNodes.Value (aNodeIter);
+ anArray->SetValue (aNodeIter + 1, aPnt);
+ }
+ return anArray;
}
//=======================================================================
}
}
+// =======================================================================
+// function : SetDoublePrecision
+// purpose :
+// =======================================================================
+void Poly_Triangulation::SetDoublePrecision (bool theIsDouble)
+{
+ myNodes .SetDoublePrecision (theIsDouble);
+ myUVNodes.SetDoublePrecision (theIsDouble);
+}
+
// =======================================================================
// function : ResizeNodes
// purpose :
void Poly_Triangulation::ResizeNodes (Standard_Integer theNbNodes,
Standard_Boolean theToCopyOld)
{
- myNodes.Resize (1, theNbNodes, theToCopyOld);
+ myNodes.Resize (theNbNodes, theToCopyOld);
if (!myUVNodes.IsEmpty())
{
- myUVNodes.Resize (1, theNbNodes, theToCopyOld);
+ myUVNodes.Resize (theNbNodes, theToCopyOld);
}
if (!myNormals.IsEmpty())
{
- myNormals.Resize (1, theNbNodes, theToCopyOld);
+ myNormals.Resize (0, theNbNodes - 1, theToCopyOld);
}
}
{
if (myUVNodes.IsEmpty() || myUVNodes.Size() != myNodes.Size())
{
- myUVNodes.Resize (1, myNodes.Size(), false);
+ myUVNodes.Resize (myNodes.Size(), false);
}
}
{
if (myNormals.IsEmpty() || myNormals.Size() != myNodes.Size())
{
- myNormals.Resize (1, myNodes.Size(), false);
+ myNormals.Resize (0, myNodes.Size() - 1, false);
}
}
Bnd_Box aBox;
if (theTrsf.Form() == gp_Identity)
{
- for (Standard_Integer aNodeIdx = 1; aNodeIdx <= NbNodes(); aNodeIdx++)
+ for (Standard_Integer aNodeIdx = 0; aNodeIdx < NbNodes(); aNodeIdx++)
{
- aBox.Add (myNodes[aNodeIdx]);
+ aBox.Add (myNodes.Value (aNodeIdx));
}
}
else
{
- for (Standard_Integer aNodeIdx = 1; aNodeIdx <= NbNodes(); aNodeIdx++)
+ for (Standard_Integer aNodeIdx = 0; aNodeIdx < NbNodes(); aNodeIdx++)
{
- aBox.Add (myNodes[aNodeIdx].Transformed (theTrsf));
+ aBox.Add (myNodes.Value (aNodeIdx).Transformed (theTrsf));
}
}
return aBox;
for (Poly_Array1OfTriangle::Iterator aTriIter (myTriangles); aTriIter.More(); aTriIter.Next())
{
aTriIter.Value().Get (anElem[0], anElem[1], anElem[2]);
- const gp_Pnt aNode0 = myNodes.Value (anElem[0]);
- const gp_Pnt aNode1 = myNodes.Value (anElem[1]);
- const gp_Pnt aNode2 = myNodes.Value (anElem[2]);
+ const gp_Pnt aNode0 = myNodes.Value (anElem[0] - 1);
+ const gp_Pnt aNode1 = myNodes.Value (anElem[1] - 1);
+ const gp_Pnt aNode2 = myNodes.Value (anElem[2] - 1);
const gp_XYZ aVec01 = aNode1.XYZ() - aNode0.XYZ();
const gp_XYZ aVec02 = aNode2.XYZ() - aNode0.XYZ();
const gp_Vec3f aNorm3f = gp_Vec3f (float(aTriNorm.X()), float(aTriNorm.Y()), float(aTriNorm.Z()));
for (Standard_Integer aNodeIter = 0; aNodeIter < 3; ++aNodeIter)
{
- myNormals.ChangeValue (anElem[aNodeIter]) += aNorm3f;
+ myNormals.ChangeValue (anElem[aNodeIter] - 1) += aNorm3f;
}
}
#include <Bnd_Box.hxx>
#include <gp_Vec3f.hxx>
#include <Poly_HArray1OfTriangle.hxx>
+#include <Poly_ArrayOfNodes.hxx>
+#include <Poly_ArrayOfUVNodes.hxx>
#include <TColgp_HArray1OfPnt.hxx>
#include <TColgp_HArray1OfPnt2d.hxx>
#include <TShort_HArray1OfShortReal.hxx>
Standard_Boolean HasNormals() const { return !myNormals.IsEmpty(); }
//! Returns a node at the given index.
- const gp_Pnt& Node (Standard_Integer theIndex) const { return myNodes.Value (theIndex); }
+ gp_Pnt Node (Standard_Integer theIndex) const { return myNodes.Value (theIndex - 1); }
//! Sets a node coordinates.
void SetNode (Standard_Integer theIndex,
const gp_Pnt& thePnt)
{
- myNodes.SetValue (theIndex, thePnt);
+ myNodes.SetValue (theIndex - 1, thePnt);
}
//! Returns UV-node at the given index.
- const gp_Pnt2d& UVNode (Standard_Integer theIndex) const { return myUVNodes.Value (theIndex); }
+ gp_Pnt2d UVNode (Standard_Integer theIndex) const { return myUVNodes.Value (theIndex - 1); }
//! Sets an UV-node coordinates.
void SetUVNode (Standard_Integer theIndex,
const gp_Pnt2d& thePnt)
{
- myUVNodes.SetValue (theIndex, thePnt);
+ myUVNodes.SetValue (theIndex - 1, thePnt);
}
//! Returns triangle at the given index.
//! Returns normal at the given index.
gp_Dir Normal (Standard_Integer theIndex) const
{
- const gp_Vec3f& aNorm = myNormals.Value (theIndex);
+ const gp_Vec3f& aNorm = myNormals.Value (theIndex - 1);
return gp_Dir (aNorm.x(), aNorm.y(), aNorm.z());
}
void Normal (Standard_Integer theIndex,
gp_Vec3f& theVec3) const
{
- theVec3 = myNormals.Value (theIndex);
+ theVec3 = myNormals.Value (theIndex - 1);
}
//! Changes normal at the given index.
void SetNormal (const Standard_Integer theIndex,
const gp_Vec3f& theNormal)
{
- myNormals.SetValue (theIndex, theNormal);
+ myNormals.SetValue (theIndex - 1, theNormal);
}
//! Changes normal at the given index.
public:
+ //! Returns TRUE if node positions are defined with double precision; TRUE by default.
+ bool IsDoublePrecision() const { return myNodes.IsDoublePrecision(); }
+
+ //! Set if node positions should be defined with double or single precision for 3D and UV nodes.
+ //! Raises exception if data was already allocated.
+ Standard_EXPORT void SetDoublePrecision (bool theIsDouble);
+
//! Method resizing internal arrays of nodes (synchronously for all attributes).
//! @param theNbNodes [in] new number of nodes
//! @param theToCopyOld [in] copy old nodes into the new array
//! Returns an internal array of nodes.
//! Node()/SetNode() should be used instead in portable code.
- TColgp_Array1OfPnt& InternalNodes() { return myNodes; }
+ Poly_ArrayOfNodes& InternalNodes() { return myNodes; }
//! Returns an internal array of UV nodes.
//! UBNode()/SetUVNode() should be used instead in portable code.
- TColgp_Array1OfPnt2d& InternalUVNodes() { return myUVNodes; }
+ Poly_ArrayOfUVNodes& InternalUVNodes() { return myUVNodes; }
//! Return an internal array of normals.
//! Normal()/SetNormal() should be used instead in portable code.
Standard_DEPRECATED("Deprecated method, SetNormal() should be used instead")
Standard_EXPORT void SetNormals (const Handle(TShort_HArray1OfShortReal)& theNormals);
- Standard_DEPRECATED("Deprecated method, Node() should be used instead")
- const TColgp_Array1OfPnt& Nodes() const { return myNodes; }
-
- Standard_DEPRECATED("Deprecated method, SetNode() should be used instead")
- TColgp_Array1OfPnt& ChangeNodes() { return myNodes; }
-
- Standard_DEPRECATED("Deprecated method, SetNode() should be used instead")
- gp_Pnt& ChangeNode (const Standard_Integer theIndex) { return myNodes.ChangeValue (theIndex); }
-
- Standard_DEPRECATED("Deprecated method, UVNode() should be used instead")
- const TColgp_Array1OfPnt2d& UVNodes() const { return myUVNodes; }
-
- Standard_DEPRECATED("Deprecated method, SetUVNode() should be used instead")
- TColgp_Array1OfPnt2d& ChangeUVNodes() { return myUVNodes; }
-
- Standard_DEPRECATED("Deprecated method, SetUVNode() should be used instead")
- gp_Pnt2d& ChangeUVNode (const Standard_Integer theIndex) { return myUVNodes.ChangeValue (theIndex); }
-
Standard_DEPRECATED("Deprecated method, Triangle() should be used instead")
const Poly_Array1OfTriangle& Triangles() const { return myTriangles; }
Bnd_Box* myCachedMinMax;
Standard_Real myDeflection;
- TColgp_Array1OfPnt myNodes;
+ Poly_ArrayOfNodes myNodes;
Poly_Array1OfTriangle myTriangles;
- TColgp_Array1OfPnt2d myUVNodes;
+ Poly_ArrayOfUVNodes myUVNodes;
NCollection_Array1<gp_Vec3f> myNormals;
};
RWGltf_CafReader::RWGltf_CafReader()
: myToParallel (false),
myToSkipEmptyNodes (true),
- myUseMeshNameAsFallback (true)
+ myUseMeshNameAsFallback (true),
+ myIsDoublePrecision (false)
{
myCoordSysConverter.SetInputLengthUnit (1.0); // glTF defines model in meters
myCoordSysConverter.SetInputCoordinateSystem (RWMesh_CoordinateSystem_glTF);
Handle(RWGltf_PrimitiveArrayReader) RWGltf_CafReader::createMeshReaderContext()
{
Handle(RWGltf_TriangulationReader) aReader = new RWGltf_TriangulationReader();
+ aReader->SetDoublePrecision (myIsDoublePrecision);
return aReader;
}
//! Set flag to use Mesh name in case if Node name is empty.
void SetMeshNameAsFallback (bool theToFallback) { myUseMeshNameAsFallback = theToFallback; }
+ //! Return flag to fill in triangulation using double or single precision; FALSE by default.
+ bool IsDoublePrecision() const { return myIsDoublePrecision; }
+
+ //! Set flag to fill in triangulation using double or single precision.
+ void SetDoublePrecision (bool theIsDouble) { myIsDoublePrecision = theIsDouble; }
+
protected:
//! Read the mesh from specified file.
Standard_Boolean myToParallel; //!< flag to use multithreading; FALSE by default
Standard_Boolean myToSkipEmptyNodes; //!< ignore nodes without Geometry; TRUE by default
Standard_Boolean myUseMeshNameAsFallback; //!< flag to use Mesh name in case if Node name is empty, TRUE by default
+ Standard_Boolean myIsDoublePrecision; //!< flag to fill in triangulation using single or double precision
};
// purpose :
// =======================================================================
RWGltf_TriangulationReader::RWGltf_TriangulationReader()
+: myIsDoublePrecision (false)
{
//
}
void RWGltf_TriangulationReader::reset()
{
myTriangulation = new Poly_Triangulation();
+ myTriangulation->SetDoublePrecision (myIsDoublePrecision);
}
// =======================================================================
//! Empty constructor.
Standard_EXPORT RWGltf_TriangulationReader();
+ //! Return flag to fill in triangulation using double or single precision; FALSE by default.
+ bool IsDoublePrecision() const { return myIsDoublePrecision; }
+
+ //! Set flag to fill in triangulation using double or single precision.
+ void SetDoublePrecision (bool theIsDouble) { myIsDoublePrecision = theIsDouble; }
+
protected:
//! Create Poly_Triangulation from collected data
protected:
Handle(Poly_Triangulation) myTriangulation;
+ Standard_Boolean myIsDoublePrecision;
};
Standard_Real aSystemUnitFactor = UnitsMethods::GetCasCadeLengthUnit() * 0.001;
Standard_Boolean toListExternalFiles = Standard_False;
Standard_Boolean isParallel = Standard_False;
+ Standard_Boolean isDoublePrec = Standard_False;
Standard_Boolean isNoDoc = (TCollection_AsciiString(theArgVec[0]) == "readgltf");
for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
{
++anArgIter;
}
}
+ else if (anArgCase == "-doubleprec"
+ || anArgCase == "-doubleprecision"
+ || anArgCase == "-singleprec"
+ || anArgCase == "-singleprecision")
+ {
+ isDoublePrec = Standard_True;
+ if (anArgIter + 1 < theNbArgs
+ && Draw::ParseOnOff (theArgVec[anArgIter + 1], isDoublePrec))
+ {
+ ++anArgIter;
+ }
+ if (anArgCase.StartsWith ("-single"))
+ {
+ isDoublePrec = !isDoublePrec;
+ }
+ }
else if (anArgCase == "-listexternalfiles"
|| anArgCase == "-listexternals"
|| anArgCase == "-listexternal"
aReader.SetSystemCoordinateSystem (RWMesh_CoordinateSystem_Zup);
aReader.SetDocument (aDoc);
aReader.SetParallel (isParallel);
+ aReader.SetDoublePrecision (isDoublePrec);
if (toListExternalFiles)
{
aReader.ProbeHeader (aFilePath);
//XSDRAW::LoadDraw(theCommands);
theCommands.Add ("ReadGltf",
- "ReadGltf Doc file [-parallel {on|off}] [-listExternalFiles] [-noCreateDoc]"
+ "ReadGltf Doc file [-parallel {on|off}] [-listExternalFiles] [-noCreateDoc] [-doublePrecision {on|off}]"
"\n\t\t: Read glTF file into XDE document."
"\n\t\t: -listExternalFiles do not read mesh and only list external files"
- "\n\t\t: -noCreateDoc read into existing XDE document",
+ "\n\t\t: -noCreateDoc read into existing XDE document"
+ "\n\t\t: -doublePrecision store triangulation with double or single floating point"
+ "\n\t\t: precision (single by default)",
__FILE__, ReadGltf, g);
theCommands.Add ("readgltf",
"readgltf shape file"