diff --git a/src/DataExchange/TKDESTEP/GTests/FILES.cmake b/src/DataExchange/TKDESTEP/GTests/FILES.cmake index d51e3db502..5c9e8bce83 100644 --- a/src/DataExchange/TKDESTEP/GTests/FILES.cmake +++ b/src/DataExchange/TKDESTEP/GTests/FILES.cmake @@ -14,5 +14,6 @@ set(OCCT_TKDESTEP_GTests_FILES StepTidy_PlaneReducer_Test.cxx StepTidy_Merger_Test.cxx StepTidy_VectorReducer_Test.cxx + StepToTopoDS_TranslateFace_Test.cxx StepTransientReplacements_Test.cxx ) diff --git a/src/DataExchange/TKDESTEP/GTests/StepToTopoDS_TranslateFace_Test.cxx b/src/DataExchange/TKDESTEP/GTests/StepToTopoDS_TranslateFace_Test.cxx new file mode 100644 index 0000000000..e6463872cc --- /dev/null +++ b/src/DataExchange/TKDESTEP/GTests/StepToTopoDS_TranslateFace_Test.cxx @@ -0,0 +1,552 @@ +// Copyright (c) 2025 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace +{ + +// Helper: create a CoordinatesList with given points. +static occ::handle createCoords( + const NCollection_Array1& thePoints) +{ + occ::handle> aPoints = + new NCollection_HArray1(thePoints.Lower(), thePoints.Upper()); + for (int i = thePoints.Lower(); i <= thePoints.Upper(); ++i) + { + aPoints->SetValue(i, thePoints.Value(i)); + } + occ::handle aCoords = new StepVisual_CoordinatesList(); + aCoords->Init(new TCollection_HAsciiString("coords"), aPoints); + return aCoords; +} + +// Helper: create a 2D int array for triangles (NRows x 3). +static occ::handle> createTriangles( + const NCollection_Array1>& theTriData) +{ + const int aNbTri = theTriData.Length(); + occ::handle> aTriangles = new NCollection_HArray2(1, aNbTri, 1, 3); + for (int i = 1; i <= aNbTri; ++i) + { + const NCollection_Array1& aTri = theTriData.Value(theTriData.Lower() + i - 1); + aTriangles->SetValue(i, 1, aTri.Value(aTri.Lower())); + aTriangles->SetValue(i, 2, aTri.Value(aTri.Lower() + 1)); + aTriangles->SetValue(i, 3, aTri.Value(aTri.Lower() + 2)); + } + return aTriangles; +} + +// Helper: create normals array (NRows x 3). +static occ::handle> createNormals( + const NCollection_Array1& theNorms) +{ + const int aNbNorms = theNorms.Length(); + occ::handle> aNormals = + new NCollection_HArray2(1, aNbNorms, 1, 3); + for (int i = 1; i <= aNbNorms; ++i) + { + const gp_XYZ& aN = theNorms.Value(theNorms.Lower() + i - 1); + aNormals->SetValue(i, 1, aN.X()); + aNormals->SetValue(i, 2, aN.Y()); + aNormals->SetValue(i, 3, aN.Z()); + } + return aNormals; +} + +// Helper: extract Poly_Triangulation from translated face result. +static occ::handle getMesh(const StepToTopoDS_TranslateFace& theTranslator) +{ + EXPECT_TRUE(theTranslator.IsDone()); + const TopoDS_Face& aFace = TopoDS::Face(theTranslator.Value()); + TopLoc_Location aLoc; + return BRep_Tool::Triangulation(aFace, aLoc); +} + +// Fixture providing common setup for all tests. +class StepToTopoDS_TranslateFaceTest : public testing::Test +{ +protected: + void SetUp() override + { + occ::handle aTP = new Transfer_TransientProcess(); + NCollection_DataMap, TopoDS_Shape> aMap; + myTool.Init(aMap, aTP); + myNMTool.SetActive(false); + } + + StepToTopoDS_Tool myTool; + StepToTopoDS_NMTool myNMTool; +}; + +} // namespace + +// Test: TriangulatedFace with direct node indexing (no pnindex). +TEST_F(StepToTopoDS_TranslateFaceTest, TriangulatedFace_DirectNodes) +{ + NCollection_Array1 aPoints(1, 4); + aPoints.SetValue(1, gp_XYZ(0.0, 0.0, 0.0)); + aPoints.SetValue(2, gp_XYZ(1.0, 0.0, 0.0)); + aPoints.SetValue(3, gp_XYZ(1.0, 1.0, 0.0)); + aPoints.SetValue(4, gp_XYZ(0.0, 1.0, 0.0)); + + NCollection_Array1> aTriData(1, 2); + aTriData.ChangeValue(1) = NCollection_Array1(0, 2); + aTriData.ChangeValue(1).SetValue(0, 1); + aTriData.ChangeValue(1).SetValue(1, 2); + aTriData.ChangeValue(1).SetValue(2, 3); + aTriData.ChangeValue(2) = NCollection_Array1(0, 2); + aTriData.ChangeValue(2).SetValue(0, 1); + aTriData.ChangeValue(2).SetValue(1, 3); + aTriData.ChangeValue(2).SetValue(2, 4); + + occ::handle aTF = new StepVisual_TriangulatedFace(); + aTF->Init(new TCollection_HAsciiString("face"), + createCoords(aPoints), + 4, + nullptr, + false, + StepVisual_FaceOrSurface(), + nullptr, + createTriangles(aTriData)); + + bool aHasGeom = false; + StepToTopoDS_TranslateFace aTranslator(aTF, myTool, myNMTool, false, aHasGeom); + + occ::handle aMesh = getMesh(aTranslator); + ASSERT_FALSE(aMesh.IsNull()); + EXPECT_EQ(aMesh->NbNodes(), 4); + EXPECT_EQ(aMesh->NbTriangles(), 2); + EXPECT_FALSE(aMesh->HasNormals()); + + EXPECT_NEAR(aMesh->Node(1).X(), 0.0, 1e-12); + EXPECT_NEAR(aMesh->Node(2).X(), 1.0, 1e-12); + EXPECT_NEAR(aMesh->Node(3).Y(), 1.0, 1e-12); + + int aN1, aN2, aN3; + aMesh->Triangle(1).Get(aN1, aN2, aN3); + EXPECT_EQ(aN1, 1); + EXPECT_EQ(aN2, 2); + EXPECT_EQ(aN3, 3); +} + +// Test: TriangulatedFace with pnindex remapping. +TEST_F(StepToTopoDS_TranslateFaceTest, TriangulatedFace_WithPnindex) +{ + // 4 points defined but pnindex selects only 3 of them. + NCollection_Array1 aPoints(1, 4); + aPoints.SetValue(1, gp_XYZ(0.0, 0.0, 0.0)); + aPoints.SetValue(2, gp_XYZ(10.0, 0.0, 0.0)); + aPoints.SetValue(3, gp_XYZ(10.0, 10.0, 0.0)); + aPoints.SetValue(4, gp_XYZ(0.0, 10.0, 0.0)); + + // Pnindex: mesh nodes 1,2,3 map to coordinate indices 2,3,4. + occ::handle> aPnindex = new NCollection_HArray1(1, 3); + aPnindex->SetValue(1, 2); + aPnindex->SetValue(2, 3); + aPnindex->SetValue(3, 4); + + NCollection_Array1> aTriData(1, 1); + aTriData.ChangeValue(1) = NCollection_Array1(0, 2); + aTriData.ChangeValue(1).SetValue(0, 1); + aTriData.ChangeValue(1).SetValue(1, 2); + aTriData.ChangeValue(1).SetValue(2, 3); + + occ::handle aTF = new StepVisual_TriangulatedFace(); + aTF->Init(new TCollection_HAsciiString("face"), + createCoords(aPoints), + 4, + nullptr, + false, + StepVisual_FaceOrSurface(), + aPnindex, + createTriangles(aTriData)); + + bool aHasGeom = false; + StepToTopoDS_TranslateFace aTranslator(aTF, myTool, myNMTool, false, aHasGeom); + + occ::handle aMesh = getMesh(aTranslator); + ASSERT_FALSE(aMesh.IsNull()); + EXPECT_EQ(aMesh->NbNodes(), 3); + EXPECT_EQ(aMesh->NbTriangles(), 1); + + // Node 1 should be coordinate 2 (10,0,0). + EXPECT_NEAR(aMesh->Node(1).X(), 10.0, 1e-12); + EXPECT_NEAR(aMesh->Node(1).Y(), 0.0, 1e-12); + // Node 2 should be coordinate 3 (10,10,0). + EXPECT_NEAR(aMesh->Node(2).X(), 10.0, 1e-12); + EXPECT_NEAR(aMesh->Node(2).Y(), 10.0, 1e-12); + // Node 3 should be coordinate 4 (0,10,0). + EXPECT_NEAR(aMesh->Node(3).X(), 0.0, 1e-12); + EXPECT_NEAR(aMesh->Node(3).Y(), 10.0, 1e-12); +} + +// Test: TriangulatedSurfaceSet with direct nodes (no pnindex). +TEST_F(StepToTopoDS_TranslateFaceTest, TriangulatedSurfaceSet_DirectNodes) +{ + NCollection_Array1 aPoints(1, 3); + aPoints.SetValue(1, gp_XYZ(0.0, 0.0, 0.0)); + aPoints.SetValue(2, gp_XYZ(2.0, 0.0, 0.0)); + aPoints.SetValue(3, gp_XYZ(1.0, 2.0, 0.0)); + + NCollection_Array1> aTriData(1, 1); + aTriData.ChangeValue(1) = NCollection_Array1(0, 2); + aTriData.ChangeValue(1).SetValue(0, 1); + aTriData.ChangeValue(1).SetValue(1, 2); + aTriData.ChangeValue(1).SetValue(2, 3); + + occ::handle aTSS = new StepVisual_TriangulatedSurfaceSet(); + aTSS->Init(new TCollection_HAsciiString("surfset"), + createCoords(aPoints), + 3, + nullptr, + nullptr, + createTriangles(aTriData)); + + StepToTopoDS_TranslateFace aTranslator(aTSS, myTool, myNMTool); + + occ::handle aMesh = getMesh(aTranslator); + ASSERT_FALSE(aMesh.IsNull()); + EXPECT_EQ(aMesh->NbNodes(), 3); + EXPECT_EQ(aMesh->NbTriangles(), 1); + + EXPECT_NEAR(aMesh->Node(1).X(), 0.0, 1e-12); + EXPECT_NEAR(aMesh->Node(2).X(), 2.0, 1e-12); + EXPECT_NEAR(aMesh->Node(3).Y(), 2.0, 1e-12); +} + +// Test: TriangulatedSurfaceSet with pnindex remapping. +TEST_F(StepToTopoDS_TranslateFaceTest, TriangulatedSurfaceSet_WithPnindex) +{ + NCollection_Array1 aPoints(1, 4); + aPoints.SetValue(1, gp_XYZ(0.0, 0.0, 0.0)); + aPoints.SetValue(2, gp_XYZ(5.0, 0.0, 0.0)); + aPoints.SetValue(3, gp_XYZ(5.0, 5.0, 0.0)); + aPoints.SetValue(4, gp_XYZ(0.0, 5.0, 0.0)); + + // Pnindex selects 3 out of 4 coordinates (indices 1, 3, 4). + occ::handle> aPnindex = new NCollection_HArray1(1, 3); + aPnindex->SetValue(1, 1); + aPnindex->SetValue(2, 3); + aPnindex->SetValue(3, 4); + + NCollection_Array1> aTriData(1, 1); + aTriData.ChangeValue(1) = NCollection_Array1(0, 2); + aTriData.ChangeValue(1).SetValue(0, 1); + aTriData.ChangeValue(1).SetValue(1, 2); + aTriData.ChangeValue(1).SetValue(2, 3); + + occ::handle aTSS = new StepVisual_TriangulatedSurfaceSet(); + aTSS->Init(new TCollection_HAsciiString("surfset"), + createCoords(aPoints), + 4, + nullptr, + aPnindex, + createTriangles(aTriData)); + + StepToTopoDS_TranslateFace aTranslator(aTSS, myTool, myNMTool); + + occ::handle aMesh = getMesh(aTranslator); + ASSERT_FALSE(aMesh.IsNull()); + EXPECT_EQ(aMesh->NbNodes(), 3); + + // Node 1 = coord 1 (0,0,0). + EXPECT_NEAR(aMesh->Node(1).X(), 0.0, 1e-12); + // Node 2 = coord 3 (5,5,0). + EXPECT_NEAR(aMesh->Node(2).X(), 5.0, 1e-12); + EXPECT_NEAR(aMesh->Node(2).Y(), 5.0, 1e-12); + // Node 3 = coord 4 (0,5,0). + EXPECT_NEAR(aMesh->Node(3).X(), 0.0, 1e-12); + EXPECT_NEAR(aMesh->Node(3).Y(), 5.0, 1e-12); +} + +// Test: TriangulatedFace with per-node normals. +TEST_F(StepToTopoDS_TranslateFaceTest, TriangulatedFace_WithNormals) +{ + NCollection_Array1 aPoints(1, 3); + aPoints.SetValue(1, gp_XYZ(0.0, 0.0, 0.0)); + aPoints.SetValue(2, gp_XYZ(1.0, 0.0, 0.0)); + aPoints.SetValue(3, gp_XYZ(0.0, 1.0, 0.0)); + + NCollection_Array1 aNorms(1, 3); + aNorms.SetValue(1, gp_XYZ(0.0, 0.0, 1.0)); + aNorms.SetValue(2, gp_XYZ(0.0, 0.0, 1.0)); + aNorms.SetValue(3, gp_XYZ(0.0, 0.0, 1.0)); + + NCollection_Array1> aTriData(1, 1); + aTriData.ChangeValue(1) = NCollection_Array1(0, 2); + aTriData.ChangeValue(1).SetValue(0, 1); + aTriData.ChangeValue(1).SetValue(1, 2); + aTriData.ChangeValue(1).SetValue(2, 3); + + occ::handle aTF = new StepVisual_TriangulatedFace(); + aTF->Init(new TCollection_HAsciiString("face"), + createCoords(aPoints), + 3, + createNormals(aNorms), + false, + StepVisual_FaceOrSurface(), + nullptr, + createTriangles(aTriData)); + + bool aHasGeom = false; + StepToTopoDS_TranslateFace aTranslator(aTF, myTool, myNMTool, false, aHasGeom); + + occ::handle aMesh = getMesh(aTranslator); + ASSERT_FALSE(aMesh.IsNull()); + EXPECT_TRUE(aMesh->HasNormals()); + + const gp_Dir aNormal = aMesh->Normal(1); + EXPECT_NEAR(aNormal.Z(), 1.0, 1e-12); +} + +// Test: TriangulatedFace with single normal shared by all nodes. +TEST_F(StepToTopoDS_TranslateFaceTest, TriangulatedFace_SingleNormal) +{ + NCollection_Array1 aPoints(1, 3); + aPoints.SetValue(1, gp_XYZ(0.0, 0.0, 0.0)); + aPoints.SetValue(2, gp_XYZ(1.0, 0.0, 0.0)); + aPoints.SetValue(3, gp_XYZ(0.0, 1.0, 0.0)); + + NCollection_Array1 aNorms(1, 1); + aNorms.SetValue(1, gp_XYZ(0.0, 1.0, 0.0)); + + NCollection_Array1> aTriData(1, 1); + aTriData.ChangeValue(1) = NCollection_Array1(0, 2); + aTriData.ChangeValue(1).SetValue(0, 1); + aTriData.ChangeValue(1).SetValue(1, 2); + aTriData.ChangeValue(1).SetValue(2, 3); + + occ::handle aTF = new StepVisual_TriangulatedFace(); + aTF->Init(new TCollection_HAsciiString("face"), + createCoords(aPoints), + 3, + createNormals(aNorms), + false, + StepVisual_FaceOrSurface(), + nullptr, + createTriangles(aTriData)); + + bool aHasGeom = false; + StepToTopoDS_TranslateFace aTranslator(aTF, myTool, myNMTool, false, aHasGeom); + + occ::handle aMesh = getMesh(aTranslator); + ASSERT_FALSE(aMesh.IsNull()); + EXPECT_TRUE(aMesh->HasNormals()); + + // All 3 nodes should share the same normal (0,1,0). + for (int i = 1; i <= 3; ++i) + { + const gp_Dir aNormal = aMesh->Normal(i); + EXPECT_NEAR(aNormal.X(), 0.0, 1e-12); + EXPECT_NEAR(aNormal.Y(), 1.0, 1e-12); + EXPECT_NEAR(aNormal.Z(), 0.0, 1e-12); + } +} + +// Test: Length factor scaling of coordinates. +TEST_F(StepToTopoDS_TranslateFaceTest, TriangulatedSurfaceSet_LengthFactor) +{ + NCollection_Array1 aPoints(1, 3); + aPoints.SetValue(1, gp_XYZ(0.0, 0.0, 0.0)); + aPoints.SetValue(2, gp_XYZ(1.0, 0.0, 0.0)); + aPoints.SetValue(3, gp_XYZ(0.0, 1.0, 0.0)); + + NCollection_Array1> aTriData(1, 1); + aTriData.ChangeValue(1) = NCollection_Array1(0, 2); + aTriData.ChangeValue(1).SetValue(0, 1); + aTriData.ChangeValue(1).SetValue(1, 2); + aTriData.ChangeValue(1).SetValue(2, 3); + + occ::handle aTSS = new StepVisual_TriangulatedSurfaceSet(); + aTSS->Init(new TCollection_HAsciiString("surfset"), + createCoords(aPoints), + 3, + nullptr, + nullptr, + createTriangles(aTriData)); + + StepData_Factors aFactors; + aFactors.InitializeFactors(25.4, 1.0, 1.0); + + StepToTopoDS_TranslateFace aTranslator(aTSS, myTool, myNMTool, aFactors); + + occ::handle aMesh = getMesh(aTranslator); + ASSERT_FALSE(aMesh.IsNull()); + + // Coordinates should be scaled by length factor 25.4. + EXPECT_NEAR(aMesh->Node(2).X(), 25.4, 1e-10); + EXPECT_NEAR(aMesh->Node(3).Y(), 25.4, 1e-10); +} + +// Test: ComplexTriangulatedFace with triangle strips. +TEST_F(StepToTopoDS_TranslateFaceTest, ComplexTriangulatedFace_TriangleStrips) +{ + NCollection_Array1 aPoints(1, 4); + aPoints.SetValue(1, gp_XYZ(0.0, 0.0, 0.0)); + aPoints.SetValue(2, gp_XYZ(1.0, 0.0, 0.0)); + aPoints.SetValue(3, gp_XYZ(0.0, 1.0, 0.0)); + aPoints.SetValue(4, gp_XYZ(1.0, 1.0, 0.0)); + + // Triangle strip: [1, 2, 3, 4] produces 2 triangles. + occ::handle> aStrip = new NCollection_HArray1(1, 4); + aStrip->SetValue(1, 1); + aStrip->SetValue(2, 2); + aStrip->SetValue(3, 3); + aStrip->SetValue(4, 4); + + occ::handle>> aStrips = + new NCollection_HArray1>(1, 1); + aStrips->SetValue(1, aStrip); + + occ::handle aCTF = new StepVisual_ComplexTriangulatedFace(); + aCTF->Init(new TCollection_HAsciiString("complex_face"), + createCoords(aPoints), + 4, + nullptr, + false, + StepVisual_FaceOrSurface(), + nullptr, + aStrips, + nullptr); + + bool aHasGeom = false; + StepToTopoDS_TranslateFace aTranslator(aCTF, myTool, myNMTool, false, aHasGeom); + + occ::handle aMesh = getMesh(aTranslator); + ASSERT_FALSE(aMesh.IsNull()); + EXPECT_EQ(aMesh->NbNodes(), 4); + EXPECT_EQ(aMesh->NbTriangles(), 2); +} + +// Test: ComplexTriangulatedFace with triangle fans. +TEST_F(StepToTopoDS_TranslateFaceTest, ComplexTriangulatedFace_TriangleFans) +{ + NCollection_Array1 aPoints(1, 5); + aPoints.SetValue(1, gp_XYZ(0.0, 0.0, 0.0)); + aPoints.SetValue(2, gp_XYZ(1.0, 0.0, 0.0)); + aPoints.SetValue(3, gp_XYZ(1.0, 1.0, 0.0)); + aPoints.SetValue(4, gp_XYZ(0.0, 1.0, 0.0)); + aPoints.SetValue(5, gp_XYZ(-1.0, 0.0, 0.0)); + + // Triangle fan: [1, 2, 3, 4, 5] with center at vertex 1 produces 3 triangles. + occ::handle> aFan = new NCollection_HArray1(1, 5); + aFan->SetValue(1, 1); + aFan->SetValue(2, 2); + aFan->SetValue(3, 3); + aFan->SetValue(4, 4); + aFan->SetValue(5, 5); + + occ::handle>> aFans = + new NCollection_HArray1>(1, 1); + aFans->SetValue(1, aFan); + + occ::handle aCTF = new StepVisual_ComplexTriangulatedFace(); + aCTF->Init(new TCollection_HAsciiString("complex_face"), + createCoords(aPoints), + 5, + nullptr, + false, + StepVisual_FaceOrSurface(), + nullptr, + nullptr, + aFans); + + bool aHasGeom = false; + StepToTopoDS_TranslateFace aTranslator(aCTF, myTool, myNMTool, false, aHasGeom); + + occ::handle aMesh = getMesh(aTranslator); + ASSERT_FALSE(aMesh.IsNull()); + EXPECT_EQ(aMesh->NbNodes(), 5); + EXPECT_EQ(aMesh->NbTriangles(), 3); +} + +// Test: Null input produces no result. +TEST_F(StepToTopoDS_TranslateFaceTest, NullInput_TessellatedFace) +{ + occ::handle aNullTF; + bool aHasGeom = false; + StepToTopoDS_TranslateFace aTranslator; + aTranslator.Init(aNullTF, myTool, myNMTool, false, aHasGeom); + EXPECT_FALSE(aTranslator.IsDone()); +} + +// Test: Null input for TessellatedSurfaceSet. +TEST_F(StepToTopoDS_TranslateFaceTest, NullInput_TessellatedSurfaceSet) +{ + occ::handle aNullTSS; + StepToTopoDS_TranslateFace aTranslator; + aTranslator.Init(aNullTSS, myTool, myNMTool); + EXPECT_FALSE(aTranslator.IsDone()); +} + +// Test: ComplexTriangulatedFace with strip containing degenerate triangles (duplicate indices). +TEST_F(StepToTopoDS_TranslateFaceTest, ComplexTriangulatedFace_DegenerateStrip) +{ + NCollection_Array1 aPoints(1, 4); + aPoints.SetValue(1, gp_XYZ(0.0, 0.0, 0.0)); + aPoints.SetValue(2, gp_XYZ(1.0, 0.0, 0.0)); + aPoints.SetValue(3, gp_XYZ(0.0, 1.0, 0.0)); + aPoints.SetValue(4, gp_XYZ(1.0, 1.0, 0.0)); + + // Strip with degenerate: [1, 2, 3, 3] - the second triangle (2,3,3) is degenerate. + occ::handle> aStrip = new NCollection_HArray1(1, 4); + aStrip->SetValue(1, 1); + aStrip->SetValue(2, 2); + aStrip->SetValue(3, 3); + aStrip->SetValue(4, 3); + + occ::handle>> aStrips = + new NCollection_HArray1>(1, 1); + aStrips->SetValue(1, aStrip); + + occ::handle aCTF = new StepVisual_ComplexTriangulatedFace(); + aCTF->Init(new TCollection_HAsciiString("complex_face"), + createCoords(aPoints), + 4, + nullptr, + false, + StepVisual_FaceOrSurface(), + nullptr, + aStrips, + nullptr); + + bool aHasGeom = false; + StepToTopoDS_TranslateFace aTranslator(aCTF, myTool, myNMTool, false, aHasGeom); + + occ::handle aMesh = getMesh(aTranslator); + ASSERT_FALSE(aMesh.IsNull()); + // Only 1 non-degenerate triangle from strip [1,2,3,3]. + EXPECT_EQ(aMesh->NbTriangles(), 1); +} diff --git a/src/DataExchange/TKDESTEP/StepToTopoDS/StepToTopoDS_TranslateFace.cxx b/src/DataExchange/TKDESTEP/StepToTopoDS/StepToTopoDS_TranslateFace.cxx index 7d74d109bd..86776248fc 100644 --- a/src/DataExchange/TKDESTEP/StepToTopoDS/StepToTopoDS_TranslateFace.cxx +++ b/src/DataExchange/TKDESTEP/StepToTopoDS/StepToTopoDS_TranslateFace.cxx @@ -107,15 +107,23 @@ namespace // ============================================================================ static void SetNodes(const occ::handle& theMesh, occ::handle>& theNodes, - const int theNumPnindex, occ::handle>& thePnindices, const double theLengthFactor) { - for (int aPnIndex = 1; aPnIndex <= theMesh->NbNodes(); ++aPnIndex) + if (!thePnindices.IsNull()) { - const gp_XYZ& aPoint = - theNodes->Value((theNumPnindex > 0) ? thePnindices->Value(aPnIndex) : aPnIndex); - theMesh->SetNode(aPnIndex, theLengthFactor * aPoint); + for (int aPnIndex = 1; aPnIndex <= theMesh->NbNodes(); ++aPnIndex) + { + const gp_XYZ& aPoint = theNodes->Value(thePnindices->Value(aPnIndex)); + theMesh->SetNode(aPnIndex, theLengthFactor * aPoint); + } + } + else + { + for (int aPnIndex = 1; aPnIndex <= theMesh->NbNodes(); ++aPnIndex) + { + theMesh->SetNode(aPnIndex, theLengthFactor * theNodes->Value(aPnIndex)); + } } } @@ -126,7 +134,7 @@ static void SetNodes(const occ::handle& theMesh, static void SetNormals(const occ::handle& theMesh, const occ::handle>& theNormals, const int theNormNum, - const int theNumPnindex) + const int theNbNodes) { if (theNormals->RowLength() != 3) { @@ -138,12 +146,12 @@ static void SetNormals(const occ::handle& theMesh, aNorm.SetX(theNormals->Value(1, 1)); aNorm.SetY(theNormals->Value(1, 2)); aNorm.SetZ(theNormals->Value(1, 3)); - for (int aPnIndex = 1; aPnIndex <= theNumPnindex; ++aPnIndex) + for (int aNodeIndex = 1; aNodeIndex <= theNbNodes; ++aNodeIndex) { - theMesh->SetNormal(aPnIndex, aNorm); + theMesh->SetNormal(aNodeIndex, aNorm); } } - else if (theNumPnindex == theNormNum) + else if (theNbNodes == theNormNum) { for (int aNormIndex = 1; aNormIndex <= theNormNum; ++aNormIndex) { @@ -235,21 +243,23 @@ static void GetSimpleFaceElements(const Type& theF occ::handle>& theNodes, occ::handle>& theNormals, occ::handle>& theTriangles, - int& thePnIndNb, int& theNormNb, int& theTriNb, occ::handle>& thePnindices) { - theNodes = theFace->Coordinates()->Points(); - theNormals = theFace->Normals(); - theTriangles = theFace->Triangles(); - thePnIndNb = theFace->NbPnindex(); - theNormNb = theFace->NbNormals(); - theTriNb = theFace->NbTriangles(); - thePnindices = new NCollection_HArray1(1, thePnIndNb); - for (int anIndx = 1; anIndx <= thePnIndNb; ++anIndx) + theNodes = theFace->Coordinates()->Points(); + theNormals = theFace->Normals(); + theTriangles = theFace->Triangles(); + theNormNb = theFace->NbNormals(); + theTriNb = theFace->NbTriangles(); + const int aPnIndNb = theFace->NbPnindex(); + if (aPnIndNb > 0) { - thePnindices->SetValue(anIndx, theFace->PnindexValue(anIndx)); + thePnindices = new NCollection_HArray1(1, aPnIndNb); + for (int anIndx = 1; anIndx <= aPnIndNb; ++anIndx) + { + thePnindices->SetValue(anIndx, theFace->PnindexValue(anIndx)); + } } } @@ -264,24 +274,26 @@ static void GetComplexFaceElements( occ::handle>& theNormals, occ::handle>>& theTriangleStrips, occ::handle>>& theTriangleFans, - int& thePnIndNb, int& theNormNb, int& theTriStripsNb, int& theTriFansNb, occ::handle>& thePnindices) { - theNodes = theFace->Coordinates()->Points(); - theNormals = theFace->Normals(); - theTriangleStrips = theFace->TriangleStrips(); - theTriangleFans = theFace->TriangleFans(); - thePnIndNb = theFace->NbPnindex(); - theNormNb = theFace->NbNormals(); - theTriStripsNb = theFace->NbTriangleStrips(); - theTriFansNb = theFace->NbTriangleFans(); - thePnindices = new NCollection_HArray1(1, thePnIndNb); - for (int anIndx = 1; anIndx <= thePnIndNb; ++anIndx) + theNodes = theFace->Coordinates()->Points(); + theNormals = theFace->Normals(); + theTriangleStrips = theFace->TriangleStrips(); + theTriangleFans = theFace->TriangleFans(); + theNormNb = theFace->NbNormals(); + theTriStripsNb = theFace->NbTriangleStrips(); + theTriFansNb = theFace->NbTriangleFans(); + const int aPnIndNb = theFace->NbPnindex(); + if (aPnIndNb > 0) { - thePnindices->SetValue(anIndx, theFace->PnindexValue(anIndx)); + thePnindices = new NCollection_HArray1(1, aPnIndNb); + for (int anIndx = 1; anIndx <= aPnIndNb; ++anIndx) + { + thePnindices->SetValue(anIndx, theFace->PnindexValue(anIndx)); + } } } @@ -302,9 +314,8 @@ static occ::handle CreatePolyTriangulation( occ::handle> aNodes; occ::handle> aNormals; occ::handle> aTriangles; - int aNumPnindex = 0; - int aNormNum = 0; - int aTrianNum = 0; + int aNormNum = 0; + int aTrianNum = 0; occ::handle> aPnindices; occ::handle>> aTriaStrips; @@ -316,27 +327,13 @@ static occ::handle CreatePolyTriangulation( { occ::handle aTF = occ::down_cast(theTI); - GetSimpleFaceElements(aTF, - aNodes, - aNormals, - aTriangles, - aNumPnindex, - aNormNum, - aTrianNum, - aPnindices); + GetSimpleFaceElements(aTF, aNodes, aNormals, aTriangles, aNormNum, aTrianNum, aPnindices); } else if (theTI->IsKind(STANDARD_TYPE(StepVisual_TriangulatedSurfaceSet))) { occ::handle aTSS = occ::down_cast(theTI); - GetSimpleFaceElements(aTSS, - aNodes, - aNormals, - aTriangles, - aNumPnindex, - aNormNum, - aTrianNum, - aPnindices); + GetSimpleFaceElements(aTSS, aNodes, aNormals, aTriangles, aNormNum, aTrianNum, aPnindices); } else if (theTI->IsKind(STANDARD_TYPE(StepVisual_ComplexTriangulatedFace))) { @@ -347,7 +344,6 @@ static occ::handle CreatePolyTriangulation( aNormals, aTriaStrips, aTriaFans, - aNumPnindex, aNormNum, aTrianStripsNum, aTrianFansNum, @@ -362,7 +358,6 @@ static occ::handle CreatePolyTriangulation( aNormals, aTriaStrips, aTriaFans, - aNumPnindex, aNormNum, aTrianStripsNum, aTrianFansNum, @@ -375,7 +370,7 @@ static occ::handle CreatePolyTriangulation( const bool aHasUVNodes = false; const bool aHasNormals = (aNormNum > 0); - const int aNbNodes = (aNumPnindex > 0) ? aNumPnindex : aNodes->Length(); + const int aNbNodes = !aPnindices.IsNull() ? aPnindices->Length() : aNodes->Length(); if (aTrianStripsNum == 0 && aTrianFansNum == 0) { @@ -414,7 +409,7 @@ static occ::handle CreatePolyTriangulation( aMesh = new Poly_Triangulation(aNbNodes, aNbTriaStrips + aNbTriaFans, aHasUVNodes, aHasNormals); } - SetNodes(aMesh, aNodes, aNumPnindex, aPnindices, theLocalFactors.LengthFactor()); + SetNodes(aMesh, aNodes, aPnindices, theLocalFactors.LengthFactor()); if (aHasNormals) {