]> OCCT Git - occt.git/commitdiff
0032139: Visualization - support single-precision floating point data within Poly_Tri...
authorkgv <kgv@opencascade.com>
Wed, 17 Feb 2021 11:36:03 +0000 (14:36 +0300)
committerbugmaster <bugmaster@opencascade.com>
Sat, 20 Feb 2021 15:58:56 +0000 (18:58 +0300)
Introduced NCollection_AliasedArray collection defining a general byte array
to be aliased as array of elements of mutable type.

Poly_ArrayOfNodes specializes this interface for collecting 2d/3d points with single/double precision.
Poly_Triangulation relies on this new class for definition of 3D nodes and UV coordinates
using gp_Pnt and gp_Pnt2d by default as before.

RWGltf_CafReader now fills in triangulation using single precision by default (as stored in the file).

14 files changed:
src/NCollection/FILES
src/NCollection/NCollection_AliasedArray.hxx [new file with mode: 0644]
src/Poly/FILES
src/Poly/Poly_ArrayOfNodes.cxx [new file with mode: 0644]
src/Poly/Poly_ArrayOfNodes.hxx [new file with mode: 0644]
src/Poly/Poly_ArrayOfUVNodes.cxx [new file with mode: 0644]
src/Poly/Poly_ArrayOfUVNodes.hxx [new file with mode: 0644]
src/Poly/Poly_Triangulation.cxx
src/Poly/Poly_Triangulation.hxx
src/RWGltf/RWGltf_CafReader.cxx
src/RWGltf/RWGltf_CafReader.hxx
src/RWGltf/RWGltf_TriangulationReader.cxx
src/RWGltf/RWGltf_TriangulationReader.hxx
src/XSDRAWSTLVRML/XSDRAWSTLVRML.cxx

index d88d95895920ed7a46a8e4b6465ccefe4702ab67..56dcebaaa0d25081c988c316b20bb6802173ce27 100755 (executable)
@@ -1,5 +1,6 @@
 NCollection_AccAllocator.cxx
 NCollection_AccAllocator.hxx
+NCollection_AliasedArray.hxx
 NCollection_AlignedAllocator.cxx
 NCollection_AlignedAllocator.hxx
 NCollection_Array1.hxx
diff --git a/src/NCollection/NCollection_AliasedArray.hxx b/src/NCollection/NCollection_AliasedArray.hxx
new file mode 100644 (file)
index 0000000..fa5efeb
--- /dev/null
@@ -0,0 +1,308 @@
+// 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
index 53661cd543570e588f9501b6a0bf390b0178a88e..28292e4e40f8a430e3e9de02aef1cede4fc09654 100755 (executable)
@@ -1,6 +1,10 @@
 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
diff --git a/src/Poly/Poly_ArrayOfNodes.cxx b/src/Poly/Poly_ArrayOfNodes.cxx
new file mode 100644 (file)
index 0000000..4e0a12f
--- /dev/null
@@ -0,0 +1,61 @@
+// 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;
+}
diff --git a/src/Poly/Poly_ArrayOfNodes.hxx b/src/Poly/Poly_ArrayOfNodes.hxx
new file mode 100644 (file)
index 0000000..fda6057
--- /dev/null
@@ -0,0 +1,149 @@
+// 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
diff --git a/src/Poly/Poly_ArrayOfUVNodes.cxx b/src/Poly/Poly_ArrayOfUVNodes.cxx
new file mode 100644 (file)
index 0000000..cc73606
--- /dev/null
@@ -0,0 +1,61 @@
+// 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;
+}
diff --git a/src/Poly/Poly_ArrayOfUVNodes.hxx b/src/Poly/Poly_ArrayOfUVNodes.hxx
new file mode 100644 (file)
index 0000000..7ce3a10
--- /dev/null
@@ -0,0 +1,149 @@
+// 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
index 90ef4fe5a4bf2bac1e28b5a529c06a57326910ad..647238b9cae0d1bc06359a815adee0b6f4578952 100644 (file)
@@ -31,6 +31,7 @@ Poly_Triangulation::Poly_Triangulation()
 : myCachedMinMax (NULL),
   myDeflection   (0)
 {
+  //
 }
 
 //=======================================================================
@@ -43,16 +44,16 @@ Poly_Triangulation::Poly_Triangulation (const Standard_Integer theNbNodes,
                                         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);
   }
 }
 
@@ -64,10 +65,11 @@ Poly_Triangulation::Poly_Triangulation (const TColgp_Array1OfPnt&    theNodes,
                                         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;
 }
 
@@ -81,13 +83,15 @@ Poly_Triangulation::Poly_Triangulation (const TColgp_Array1OfPnt&    theNodes,
                                         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;
 }
 
 //=======================================================================
@@ -133,7 +137,8 @@ void Poly_Triangulation::RemoveUVNodes()
 {
   if (!myUVNodes.IsEmpty())
   {
-    TColgp_Array1OfPnt2d anEmpty;
+    Poly_ArrayOfUVNodes anEmpty;
+    anEmpty.SetDoublePrecision (myUVNodes.IsDoublePrecision());
     myUVNodes.Move (anEmpty);
   }
 }
@@ -162,10 +167,24 @@ Handle(TColgp_HArray1OfPnt) Poly_Triangulation::MapNodeArray() const
     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;
 }
 
 //=======================================================================
@@ -196,10 +215,24 @@ Handle(TColgp_HArray1OfPnt2d) Poly_Triangulation::MapUVNodeArray() const
     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;
 }
 
 //=======================================================================
@@ -242,6 +275,16 @@ void Poly_Triangulation::SetNormals (const Handle(TShort_HArray1OfShortReal)& th
   }
 }
 
+// =======================================================================
+// function : SetDoublePrecision
+// purpose  :
+// =======================================================================
+void Poly_Triangulation::SetDoublePrecision (bool theIsDouble)
+{
+  myNodes  .SetDoublePrecision (theIsDouble);
+  myUVNodes.SetDoublePrecision (theIsDouble);
+}
+
 // =======================================================================
 // function : ResizeNodes
 // purpose  :
@@ -249,14 +292,14 @@ void Poly_Triangulation::SetNormals (const Handle(TShort_HArray1OfShortReal)& th
 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);
   }
 }
 
@@ -278,7 +321,7 @@ void Poly_Triangulation::AddUVNodes()
 {
   if (myUVNodes.IsEmpty() || myUVNodes.Size() != myNodes.Size())
   {
-    myUVNodes.Resize (1, myNodes.Size(), false);
+    myUVNodes.Resize (myNodes.Size(), false);
   }
 }
 
@@ -290,7 +333,7 @@ void Poly_Triangulation::AddNormals()
 {
   if (myNormals.IsEmpty() || myNormals.Size() != myNodes.Size())
   {
-    myNormals.Resize (1, myNodes.Size(), false);
+    myNormals.Resize (0, myNodes.Size() - 1, false);
   }
 }
 
@@ -389,16 +432,16 @@ 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++)
+    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;
@@ -418,9 +461,9 @@ void Poly_Triangulation::ComputeNormals()
   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();
@@ -428,7 +471,7 @@ void Poly_Triangulation::ComputeNormals()
     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;
     }
   }
 
index c631911caf0d0f2412fd2a1a5af5c8a7c02f3411..48b4ad0f32da3f351d3f2f0a2de4cd12d55c180d 100644 (file)
@@ -20,6 +20,8 @@
 #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>
@@ -119,23 +121,23 @@ public:
   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.
@@ -151,7 +153,7 @@ public:
   //! 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());
   }
 
@@ -159,14 +161,14 @@ public:
   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.
@@ -216,6 +218,13 @@ public:
 
 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
@@ -273,11 +282,11 @@ public:
 
   //! 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.
@@ -286,24 +295,6 @@ public:
   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; }
 
@@ -326,9 +317,9 @@ protected:
 
   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;
 
 };
index 8631f0e89b7872c060942e8a53b15bacce027418..87c443d6176fe58ad49d299fc0d38dba01051b2f 100644 (file)
@@ -109,7 +109,8 @@ private:
 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);
@@ -284,6 +285,7 @@ Standard_Boolean RWGltf_CafReader::performMesh (const TCollection_AsciiString& t
 Handle(RWGltf_PrimitiveArrayReader) RWGltf_CafReader::createMeshReaderContext()
 {
   Handle(RWGltf_TriangulationReader) aReader = new RWGltf_TriangulationReader();
+  aReader->SetDoublePrecision (myIsDoublePrecision);
   return aReader;
 }
 
index baf568fad0fe5cfdedf3a344e0c514af5f9d9675..fce1c2666ce4643a4d2b809271dbbfd13a173e77 100644 (file)
@@ -49,6 +49,12 @@ public:
   //! 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.
@@ -74,6 +80,7 @@ protected:
   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
 
 };
 
index 732dc2d554b9f3fb9efac7a92a6a2cb87245c567..de4db86d8a73d5ef4efe0127eb2bda847ad8438a 100644 (file)
@@ -38,6 +38,7 @@ IMPLEMENT_STANDARD_RTTIEXT(RWGltf_TriangulationReader, RWGltf_PrimitiveArrayRead
 // purpose  :
 // =======================================================================
 RWGltf_TriangulationReader::RWGltf_TriangulationReader()
+: myIsDoublePrecision (false)
 {
   //
 }
@@ -49,6 +50,7 @@ RWGltf_TriangulationReader::RWGltf_TriangulationReader()
 void RWGltf_TriangulationReader::reset()
 {
   myTriangulation = new Poly_Triangulation();
+  myTriangulation->SetDoublePrecision (myIsDoublePrecision);
 }
 
 // =======================================================================
index dd2ef79bd3376cdcfebd7cd6e37c1b7356f4108f..a1680c0129efb15851e9470ffa5e4dad170fedba 100644 (file)
@@ -26,6 +26,12 @@ public:
   //! 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
@@ -142,6 +148,7 @@ protected: //! @name interface for filling triangulation data
 protected:
 
   Handle(Poly_Triangulation) myTriangulation;
+  Standard_Boolean myIsDoublePrecision;
 
 };
 
index 477c82ede3b32497d73856745f1a4582efdfe4f3..66370c25aef75e63e16fa163cf25ebe6965da6c8 100644 (file)
@@ -102,6 +102,7 @@ static Standard_Integer ReadGltf (Draw_Interpretor& theDI,
   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)
   {
@@ -127,6 +128,22 @@ static Standard_Integer ReadGltf (Draw_Interpretor& theDI,
         ++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"
@@ -184,6 +201,7 @@ static Standard_Integer ReadGltf (Draw_Interpretor& theDI,
   aReader.SetSystemCoordinateSystem (RWMesh_CoordinateSystem_Zup);
   aReader.SetDocument (aDoc);
   aReader.SetParallel (isParallel);
+  aReader.SetDoublePrecision (isDoublePrec);
   if (toListExternalFiles)
   {
     aReader.ProbeHeader (aFilePath);
@@ -1720,10 +1738,12 @@ void  XSDRAWSTLVRML::InitCommands (Draw_Interpretor& theCommands)
   //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"