]> OCCT Git - occt.git/commitdiff
Data Exchange - Step Direction optimization #479
authorPasukhin Dmitry <dpasukhi@opencascade.com>
Sun, 6 Apr 2025 15:48:09 +0000 (16:48 +0100)
committerGitHub <noreply@github.com>
Sun, 6 Apr 2025 15:48:09 +0000 (16:48 +0100)
Refactor direction handling in STEP files for improved clarity and performance.
Moved to use array instead of vector

src/DataExchange/TKDESTEP/RWStepGeom/RWStepGeom_RWDirection.cxx
src/DataExchange/TKDESTEP/STEPCAFControl/STEPCAFControl_Reader.cxx
src/DataExchange/TKDESTEP/StepGeom/StepGeom_CartesianPoint.cxx
src/DataExchange/TKDESTEP/StepGeom/StepGeom_CartesianPoint.hxx
src/DataExchange/TKDESTEP/StepGeom/StepGeom_Direction.cxx
src/DataExchange/TKDESTEP/StepGeom/StepGeom_Direction.hxx
src/DataExchange/TKDESTEP/StepTidy/StepTidy_DirectionHasher.pxx
src/DataExchange/TKDESTEP/StepToGeom/StepToGeom.cxx

index c41d6db127fbeb564c9ac9695a66c1e9948fb57e..cee5472fe9aa187469a4af75cd9c567891791975 100644 (file)
@@ -40,24 +40,31 @@ void RWStepGeom_RWDirection::ReadStep(const Handle(StepData_StepReaderData)& dat
 
   // --- own field : directionRatios ---
 
-  Handle(TColStd_HArray1OfReal) aDirectionRatios;
-  Standard_Real                 aDirectionRatiosItem;
-  Standard_Integer              nsub2;
-  if (data->ReadSubList(num, 2, "direction_ratios", ach, nsub2))
+  Standard_Real    aCoordinatesItem;
+  Standard_Integer aNSub2, aNbCoord = 0;
+  Standard_Real    aXYZ[3] = {0., 0., 0.};
+  if (data->ReadSubList(num, 2, "direction_ratios", ach, aNSub2))
   {
-    Standard_Integer nb2 = data->NbParams(nsub2);
-    aDirectionRatios     = new TColStd_HArray1OfReal(1, nb2);
-    for (Standard_Integer i2 = 1; i2 <= nb2; i2++)
+    Standard_Integer aNbElements = data->NbParams(aNSub2);
+    if (aNbElements > 3)
     {
-      // szv#4:S4163:12Mar99 `Standard_Boolean stat2 =` not needed
-      if (data->ReadReal(nsub2, i2, "direction_ratios", ach, aDirectionRatiosItem))
-        aDirectionRatios->SetValue(i2, aDirectionRatiosItem);
+      ach->AddWarning("More than 3 direction ratios, ignored");
+    }
+    aNbCoord = Min(aNbElements, 3);
+    for (Standard_Integer i2 = 0; i2 < aNbCoord; i2++)
+    {
+      if (data->ReadReal(aNSub2, i2 + 1, "direction_ratios", ach, aCoordinatesItem))
+      {
+        aXYZ[i2] = aCoordinatesItem;
+      }
     }
   }
 
   //--- Initialisation of the read entity ---
-
-  ent->Init(aName, aDirectionRatios);
+  if (aNbCoord == 3)
+    ent->Init3D(aName, aXYZ[0], aXYZ[1], aXYZ[2]);
+  else
+    ent->Init2D(aName, aXYZ[0], aXYZ[1]);
 }
 
 void RWStepGeom_RWDirection::WriteStep(StepData_StepWriter&              SW,
index 58845de2bfd9cb7f85c17ed3ee0e1811ed374aa0..bbd0811cdc9a75000885c1fd1c81844ad3d3f59c 100644 (file)
@@ -4393,26 +4393,19 @@ static void setDimObjectToXCAF(const Handle(Standard_Transient)&    theEnt,
           return;
         aDimObj->SetPath(aSh);
       }
-      else if (!anAP.IsNull())
+      else if (!anAP.IsNull() && !anAP->RefDirection().IsNull() && !anAP->Name().IsNull()
+               && !anAP->Axis().IsNull() && anAP->Name()->String().IsEqual("orientation"))
       {
-        if (anAP->Name()->String().IsEqual("orientation") && !anAP->Axis().IsNull())
+        // for Oriented Dimensional Location
+        const Handle(StepGeom_Direction)&   aRefDirection = anAP->RefDirection();
+        const std::array<Standard_Real, 3>& aDirArr       = aRefDirection->DirectionRatios();
+        if (aRefDirection->NbDirectionRatios() >= 3)
         {
-          // for Oriented Dimensional Location
-          Handle(TColStd_HArray1OfReal) aDirArr = anAP->RefDirection()->DirectionRatios();
-          gp_Dir                        aDir;
-          Standard_Integer              aDirLower = aDirArr->Lower();
-          if (!aDirArr.IsNull() && aDirArr->Length() > 2)
-          {
-            aDir.SetCoord(aDirArr->Value(aDirLower),
-                          aDirArr->Value(aDirLower + 1),
-                          aDirArr->Value(aDirLower + 2));
-            aDimObj->SetDirection(aDir);
-          }
-          else if (aDirArr->Length() > 1)
-          {
-            aDir.SetCoord(aDirArr->Value(aDirLower), aDirArr->Value(aDirLower + 1), 0);
-            aDimObj->SetDirection(aDir);
-          }
+          aDimObj->SetDirection({aDirArr[0], aDirArr[1], aDirArr[2]});
+        }
+        else if (aRefDirection->NbDirectionRatios() == 2)
+        {
+          aDimObj->SetDirection({aDirArr[0], aDirArr[1], 0.});
         }
       }
     }
index 078ac8c7a395b9d3d6bd007a11abc762853b2839..f5103b9717e5dad939eb581bf5e74f51870ddd9b 100644 (file)
@@ -19,71 +19,71 @@ IMPLEMENT_STANDARD_RTTIEXT(StepGeom_CartesianPoint, StepGeom_Point)
 
 StepGeom_CartesianPoint::StepGeom_CartesianPoint() {}
 
-void StepGeom_CartesianPoint::Init(const Handle(TCollection_HAsciiString)& aName,
+void StepGeom_CartesianPoint::Init(const Handle(TCollection_HAsciiString)& theName,
                                    const Handle(TColStd_HArray1OfReal)&    aCoordinates)
 {
-  // --- classe own fields ---
-  nbcoord   = aCoordinates->Length();
-  coords[0] = aCoordinates->Value(1);
-  coords[1] = aCoordinates->Value(2);
-  coords[2] = aCoordinates->Value(3);
-  //   coordinates = aCoordinates;
+  SetCoordinates(aCoordinates);
   // --- classe inherited fields ---
-  StepRepr_RepresentationItem::Init(aName);
+  StepRepr_RepresentationItem::Init(theName);
 }
 
-void StepGeom_CartesianPoint::Init2D(const Handle(TCollection_HAsciiString)& aName,
-                                     const Standard_Real                     X,
-                                     const Standard_Real                     Y)
+void StepGeom_CartesianPoint::Init2D(const Handle(TCollection_HAsciiString)& theName,
+                                     const Standard_Real                     theX,
+                                     const Standard_Real                     theY)
 {
-  nbcoord   = 2;
-  coords[0] = X;
-  coords[1] = Y;
-  coords[2] = 0;
+  myNbCoord   = 2;
+  myCoords[0] = theX;
+  myCoords[1] = theY;
+  myCoords[2] = 0;
   // --- classe inherited fields ---
-  StepRepr_RepresentationItem::Init(aName);
+  StepRepr_RepresentationItem::Init(theName);
 }
 
-void StepGeom_CartesianPoint::Init3D(const Handle(TCollection_HAsciiString)& aName,
-                                     const Standard_Real                     X,
-                                     const Standard_Real                     Y,
-                                     const Standard_Real                     Z)
+void StepGeom_CartesianPoint::Init3D(const Handle(TCollection_HAsciiString)& theName,
+                                     const Standard_Real                     theX,
+                                     const Standard_Real                     theY,
+                                     const Standard_Real                     theZ)
 {
-  nbcoord   = 3;
-  coords[0] = X;
-  coords[1] = Y;
-  coords[2] = Z;
+  myNbCoord   = 3;
+  myCoords[0] = theX;
+  myCoords[1] = theY;
+  myCoords[2] = theZ;
   // --- classe inherited fields ---
-  StepRepr_RepresentationItem::Init(aName);
+  StepRepr_RepresentationItem::Init(theName);
 }
 
 void StepGeom_CartesianPoint::SetCoordinates(const Handle(TColStd_HArray1OfReal)& aCoordinates)
 {
-  nbcoord   = aCoordinates->Length();
-  coords[0] = aCoordinates->Value(1);
-  coords[1] = aCoordinates->Value(2);
-  coords[2] = aCoordinates->Value(3);
-  //   coordinates = aCoordinates;
+  myNbCoord = aCoordinates->Length();
+  if (myNbCoord > 0)
+    myCoords[0] = aCoordinates->Value(1);
+  if (myNbCoord > 1)
+    myCoords[1] = aCoordinates->Value(2);
+  if (myNbCoord > 2)
+    myCoords[2] = aCoordinates->Value(3);
 }
 
 void StepGeom_CartesianPoint::SetCoordinates(const std::array<Standard_Real, 3>& theCoordinates)
 {
-  coords = theCoordinates;
+  myCoords = theCoordinates;
 }
 
 const std::array<Standard_Real, 3>& StepGeom_CartesianPoint::Coordinates() const
 {
-  return coords;
+  return myCoords;
 }
 
 Standard_Real StepGeom_CartesianPoint::CoordinatesValue(const Standard_Integer num) const
 {
-  return coords[num - 1];
-  //   return coordinates->Value(num);
+  return myCoords[num - 1];
+}
+
+void StepGeom_CartesianPoint::SetNbCoordinates(const Standard_Integer num)
+{
+  myNbCoord = num;
 }
 
 Standard_Integer StepGeom_CartesianPoint::NbCoordinates() const
 {
-  return nbcoord;
-  //   return coordinates->Length();
+  return myNbCoord;
 }
index 433e2679f9e4d619ed852d13d9dfd3e3891dd2c5..c294a60b33ec0c879bbaa03784085a28d0ae8a99 100644 (file)
@@ -38,34 +38,35 @@ public:
   //! Returns a CartesianPoint
   Standard_EXPORT StepGeom_CartesianPoint();
 
-  Standard_EXPORT void Init(const Handle(TCollection_HAsciiString)& aName,
-                            const Handle(TColStd_HArray1OfReal)&    aCoordinates);
+  Standard_EXPORT void Init(const Handle(TCollection_HAsciiString)& theName,
+                            const Handle(TColStd_HArray1OfReal)&    theCoordinates);
 
-  Standard_EXPORT void Init2D(const Handle(TCollection_HAsciiString)& aName,
-                              const Standard_Real                     X,
-                              const Standard_Real                     Y);
+  Standard_EXPORT void Init2D(const Handle(TCollection_HAsciiString)& theName,
+                              const Standard_Real                     theX,
+                              const Standard_Real                     theY);
 
-  Standard_EXPORT void Init3D(const Handle(TCollection_HAsciiString)& aName,
-                              const Standard_Real                     X,
-                              const Standard_Real                     Y,
-                              const Standard_Real                     Z);
+  Standard_EXPORT void Init3D(const Handle(TCollection_HAsciiString)& theName,
+                              const Standard_Real                     theX,
+                              const Standard_Real                     theY,
+                              const Standard_Real                     theZ);
 
-  Standard_EXPORT void SetCoordinates(const Handle(TColStd_HArray1OfReal)& aCoordinates);
+  Standard_EXPORT void SetCoordinates(const Handle(TColStd_HArray1OfReal)& theCoordinates);
 
   Standard_EXPORT void SetCoordinates(const std::array<Standard_Real, 3>& theCoordinates);
 
   Standard_EXPORT const std::array<Standard_Real, 3>& Coordinates() const;
 
-  Standard_EXPORT Standard_Real CoordinatesValue(const Standard_Integer num) const;
+  Standard_EXPORT Standard_Real CoordinatesValue(const Standard_Integer theInd) const;
+
+  Standard_EXPORT void SetNbCoordinates(const Standard_Integer theSize);
 
   Standard_EXPORT Standard_Integer NbCoordinates() const;
 
   DEFINE_STANDARD_RTTIEXT(StepGeom_CartesianPoint, StepGeom_Point)
 
-protected:
 private:
-  Standard_Integer             nbcoord;
-  std::array<Standard_Real, 3> coords;
+  Standard_Integer             myNbCoord;
+  std::array<Standard_Real, 3> myCoords;
 };
 
 #endif // _StepGeom_CartesianPoint_HeaderFile
index 4de29155f35f1c7fbc6c52ea8101b4c27065e361..cc23a534ac552bf4249a8e1d3c3be4a3c833a5cc 100644 (file)
@@ -18,31 +18,74 @@ IMPLEMENT_STANDARD_RTTIEXT(StepGeom_Direction, StepGeom_GeometricRepresentationI
 
 StepGeom_Direction::StepGeom_Direction() {}
 
-void StepGeom_Direction::Init(const Handle(TCollection_HAsciiString)& aName,
-                              const Handle(TColStd_HArray1OfReal)&    aDirectionRatios)
+void StepGeom_Direction::Init(const Handle(TCollection_HAsciiString)& theName,
+                              const Handle(TColStd_HArray1OfReal)&    theDirectionRatios)
 {
   // --- classe own fields ---
-  directionRatios = aDirectionRatios;
+  SetDirectionRatios(theDirectionRatios);
   // --- classe inherited fields ---
-  StepRepr_RepresentationItem::Init(aName);
+  StepRepr_RepresentationItem::Init(theName);
 }
 
-void StepGeom_Direction::SetDirectionRatios(const Handle(TColStd_HArray1OfReal)& aDirectionRatios)
+void StepGeom_Direction::Init3D(const Handle(TCollection_HAsciiString)& theName,
+                                const Standard_Real                     theDirectionRatios1,
+                                const Standard_Real                     theDirectionRatios2,
+                                const Standard_Real                     theDirectionRatios3)
 {
-  directionRatios = aDirectionRatios;
+  myNbCoord   = 3;
+  myCoords[0] = theDirectionRatios1;
+  myCoords[1] = theDirectionRatios2;
+  myCoords[2] = theDirectionRatios3;
+  // --- classe inherited fields ---
+  StepRepr_RepresentationItem::Init(theName);
+}
+
+void StepGeom_Direction::Init2D(const Handle(TCollection_HAsciiString)& theName,
+                                const Standard_Real                     theDirectionRatios1,
+                                const Standard_Real                     theDirectionRatios2)
+{
+  myNbCoord   = 2;
+  myCoords[0] = theDirectionRatios1;
+  myCoords[1] = theDirectionRatios2;
+  myCoords[2] = 0.0;
+  // --- classe inherited fields ---
+  StepRepr_RepresentationItem::Init(theName);
+}
+
+void StepGeom_Direction::SetDirectionRatios(const Handle(TColStd_HArray1OfReal)& theDirectionRatios)
+{
+  myNbCoord = theDirectionRatios->Length();
+  if (myNbCoord > 0)
+    myCoords[0] = theDirectionRatios->Value(1);
+  if (myNbCoord > 1)
+    myCoords[1] = theDirectionRatios->Value(2);
+  if (myNbCoord > 2)
+    myCoords[2] = theDirectionRatios->Value(3);
+}
+
+void StepGeom_Direction::SetDirectionRatios(const std::array<Standard_Real, 3>& theDirectionRatios)
+{
+  myCoords[0] = theDirectionRatios[0];
+  myCoords[1] = theDirectionRatios[1];
+  myCoords[2] = theDirectionRatios[2];
+}
+
+const std::array<Standard_Real, 3>& StepGeom_Direction::DirectionRatios() const
+{
+  return myCoords;
 }
 
-Handle(TColStd_HArray1OfReal) StepGeom_Direction::DirectionRatios() const
+Standard_Real StepGeom_Direction::DirectionRatiosValue(const Standard_Integer theInd) const
 {
-  return directionRatios;
+  return myCoords[theInd - 1];
 }
 
-Standard_Real StepGeom_Direction::DirectionRatiosValue(const Standard_Integer num) const
+void StepGeom_Direction::SetNbDirectionRatios(const Standard_Integer theSize)
 {
-  return directionRatios->Value(num);
+  myNbCoord = theSize;
 }
 
 Standard_Integer StepGeom_Direction::NbDirectionRatios() const
 {
-  return directionRatios->Length();
+  return myNbCoord;
 }
index f414b63419d418a239b84987091afc304ffef9e4..3f18fa28f3596f70845dda5848331da16eac6513 100644 (file)
@@ -24,6 +24,9 @@
 #include <StepGeom_GeometricRepresentationItem.hxx>
 #include <Standard_Real.hxx>
 #include <Standard_Integer.hxx>
+
+#include <array>
+
 class TCollection_HAsciiString;
 
 class StepGeom_Direction;
@@ -36,22 +39,35 @@ public:
   //! Returns a Direction
   Standard_EXPORT StepGeom_Direction();
 
-  Standard_EXPORT void Init(const Handle(TCollection_HAsciiString)& aName,
-                            const Handle(TColStd_HArray1OfReal)&    aDirectionRatios);
+  Standard_EXPORT void Init(const Handle(TCollection_HAsciiString)& theName,
+                            const Handle(TColStd_HArray1OfReal)&    theDirectionRatios);
+
+  Standard_EXPORT void Init3D(const Handle(TCollection_HAsciiString)& theName,
+                              const Standard_Real                     theDirectionRatios1,
+                              const Standard_Real                     theDirectionRatios2,
+                              const Standard_Real                     theDirectionRatios3);
+
+  Standard_EXPORT void Init2D(const Handle(TCollection_HAsciiString)& theName,
+                              const Standard_Real                     theDirectionRatios1,
+                              const Standard_Real                     theDirectionRatios2);
+
+  Standard_EXPORT void SetDirectionRatios(const Handle(TColStd_HArray1OfReal)& theDirectionRatios);
+
+  Standard_EXPORT void SetDirectionRatios(const std::array<Standard_Real, 3>& theDirectionRatios);
 
-  Standard_EXPORT void SetDirectionRatios(const Handle(TColStd_HArray1OfReal)& aDirectionRatios);
+  Standard_EXPORT const std::array<Standard_Real, 3>& DirectionRatios() const;
 
-  Standard_EXPORT Handle(TColStd_HArray1OfReal) DirectionRatios() const;
+  Standard_EXPORT Standard_Real DirectionRatiosValue(const Standard_Integer theInd) const;
 
-  Standard_EXPORT Standard_Real DirectionRatiosValue(const Standard_Integer num) const;
+  Standard_EXPORT void SetNbDirectionRatios(const Standard_Integer theSize);
 
   Standard_EXPORT Standard_Integer NbDirectionRatios() const;
 
   DEFINE_STANDARD_RTTIEXT(StepGeom_Direction, StepGeom_GeometricRepresentationItem)
 
-protected:
 private:
-  Handle(TColStd_HArray1OfReal) directionRatios;
+  Standard_Integer             myNbCoord;
+  std::array<Standard_Real, 3> myCoords;
 };
 
 #endif // _StepGeom_Direction_HeaderFile
index 3ef985ff256315457ff46b5c37c66a1a9fd9afad..d969cb405dcb25e0b0449d4d614b926082c4234c 100644 (file)
@@ -24,21 +24,17 @@ struct StepTidy_DirectionHasher
   // Hashes the direction by its name and direction ratios.
   std::size_t operator()(const Handle(StepGeom_Direction)& theDirection) const noexcept
   {
-    // Prepare an array of direction ratios.
-    const Handle(TColStd_HArray1OfReal) aCoords = theDirection->DirectionRatios();
-    int                                 anArray[3]{};
-    for (int anIndex = aCoords->Lower(); anIndex < aCoords->Upper(); ++anIndex)
-    {
-      anArray[anIndex] = static_cast<int>(aCoords->Value(anIndex));
-    }
-    // If direction has no name, hash only direction ratios.
+    const std::array<Standard_Real, 3>& aCoords = theDirection->DirectionRatios();
+    // If Cartesian point has no name, hash only directional ratios.
     if (theDirection->Name().IsNull())
     {
-      return opencascade::hashBytes(anArray, sizeof(anArray));
+      return opencascade::hashBytes(aCoords.data(), static_cast<int>(aCoords.size()));
     }
-    // Otherwise, hash both direction ratios and name.
-    const size_t aHashes[2]{opencascade::hashBytes(anArray, sizeof(anArray)),
-                            std::hash<TCollection_AsciiString>{}(theDirection->Name()->String())};
+    // Otherwise, hash both coordinates and name.
+    const size_t aHashes[2]{
+      opencascade::hashBytes(aCoords.data(), static_cast<int>(aCoords.size())),
+      std::hash<TCollection_AsciiString>{}(theDirection->Name()->String())};
+
     return opencascade::hashBytes(aHashes, sizeof(aHashes));
   }
 
@@ -58,15 +54,15 @@ struct StepTidy_DirectionHasher
 
     // Compare coordinates.
     constexpr double                    aTolerance = 1e-12;
-    const Handle(TColStd_HArray1OfReal) aCoords1   = theDirection1->DirectionRatios();
-    const Handle(TColStd_HArray1OfReal) aCoords2   = theDirection2->DirectionRatios();
-    if (aCoords1->Length() != aCoords2->Length())
+    const std::array<Standard_Real, 3>& aCoords1   = theDirection1->DirectionRatios();
+    const std::array<Standard_Real, 3>& aCoords2   = theDirection2->DirectionRatios();
+    if (theDirection1->NbDirectionRatios() != theDirection2->NbDirectionRatios())
     {
       return false;
     }
-    for (Standard_Integer i = aCoords1->Lower(); i <= aCoords1->Upper(); ++i)
+    for (int anIndex = 0; anIndex < theDirection1->NbDirectionRatios(); ++anIndex)
     {
-      if (std::abs(aCoords1->Value(i) - aCoords2->Value(i)) > aTolerance)
+      if (std::abs(aCoords1[anIndex] - aCoords2[anIndex]) > aTolerance)
       {
         return false;
       }
index 1e78d217aabbabb6ace936d584892d48ef010b2b..f67a75741b3b285fde61d79778f72cbabf9f6d90 100644 (file)
@@ -2510,7 +2510,7 @@ Handle(TColStd_HArray1OfReal) StepToGeom::MakeYprRotation(
   }
 
   if (SR.RotationAboutDirection().IsNull()
-      || SR.RotationAboutDirection()->DirectionOfAxis()->DirectionRatios()->Length() != 3
+      || SR.RotationAboutDirection()->DirectionOfAxis()->NbDirectionRatios() != 3
       || theCntxt.IsNull())
   {
     return NULL;