From: dkulikov Date: Thu, 3 Apr 2025 08:57:36 +0000 (+0100) Subject: Fixing remarks X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=709412d78a3574b6b3948ac7a36aabdd4895857f;p=occt.git Fixing remarks --- diff --git a/src/DataExchange/TKDESTEP/GTests/FILES.cmake b/src/DataExchange/TKDESTEP/GTests/FILES.cmake index 008a21f8a1..235d256623 100644 --- a/src/DataExchange/TKDESTEP/GTests/FILES.cmake +++ b/src/DataExchange/TKDESTEP/GTests/FILES.cmake @@ -2,14 +2,13 @@ set(OCCT_TKDESTEP_GTests_FILES_LOCATION "${CMAKE_CURRENT_LIST_DIR}") set(OCCT_TKDESTEP_GTests_FILES - MergeSTEPEntities_Axis2Placement3dProcessor_Test.cxx - MergeSTEPEntities_BaseTestFixture.hxx - MergeSTEPEntities_CartesianPointProcessor_Test.cxx - MergeSTEPEntities_CircleProcessor_Test.cxx - MergeSTEPEntities_DirectionProcessor_Test.cxx - MergeSTEPEntities_LineProcessor_Test.cxx - MergeSTEPEntities_PlaneProcessor_Test.cxx - MergeSTEPEntities_Merger_Test.cxx - - MergeSTEPEntities_VectorProcessor_Test.cxx + StepTidy_BaseTestFixture.pxx + StepTidy_Axis2Placement3dReducer_Test.cxx + StepTidy_CartesianPointReducer_Test.cxx + StepTidy_CircleReducer_Test.cxx + StepTidy_DirectionReducer_Test.cxx + StepTidy_LineReducer_Test.cxx + StepTidy_PlaneReducer_Test.cxx + StepTidy_Merger_Test.cxx + StepTidy_VectorReducer_Test.cxx ) diff --git a/src/DataExchange/TKDESTEP/GTests/MergeSTEPEntities_Axis2Placement3dProcessor_Test.cxx b/src/DataExchange/TKDESTEP/GTests/MergeSTEPEntities_Axis2Placement3dProcessor_Test.cxx deleted file mode 100644 index 3b8f397045..0000000000 --- a/src/DataExchange/TKDESTEP/GTests/MergeSTEPEntities_Axis2Placement3dProcessor_Test.cxx +++ /dev/null @@ -1,461 +0,0 @@ -// 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 "MergeSTEPEntities_BaseTestFixture.hxx" - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -class MergeSTEPEntities_Axis2Placement3dProcessorTest : public MergeSTEPEntities_BaseTestFixture -{ -protected: - //! Perform removal of duplicate entities. - TColStd_MapOfTransient replaceDuplicateAxis2Placement3ds() - { - MergeSTEPEntities_Axis2Placement3dProcessor aProcessor(myWS); - for (Standard_Integer anIndex = 1; anIndex <= myWS->Model()->NbEntities(); ++anIndex) - { - aProcessor.ProcessEntity(myWS->Model()->Value(anIndex)); - } - - TColStd_MapOfTransient aRemovedEntities; - aProcessor.Perform(aRemovedEntities); - return aRemovedEntities; - } -}; - -// Check that Axis2Placement3ds with the same coordinates and different names are not merged. -TEST_F(MergeSTEPEntities_Axis2Placement3dProcessorTest, DifferentNames) -{ - // Creating Axis2Placement3ds. - Handle(StepGeom_Axis2Placement3d) anAxis1 = addAxis2Placement3d("Axis1"); - Handle(StepGeom_Axis2Placement3d) anAxis2 = addAxis2Placement3d("Axis2"); - - // Creating a plane containing the first Axis2Placement3d. - Handle(StepGeom_Plane) aPlane1 = new StepGeom_Plane; - aPlane1->Init(new TCollection_HAsciiString, anAxis1); - addToModel(aPlane1); - - // Creating a plane containing the second Axis2Placement3d. - Handle(StepGeom_Plane) aPlane2 = new StepGeom_Plane; - aPlane2->Init(new TCollection_HAsciiString, anAxis2); - addToModel(aPlane2); - - // Performing removal of duplicate Axis2Placement3ds. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateAxis2Placement3ds(); - - // Check that nothing was removed. - EXPECT_TRUE(aRemovedEntities.IsEmpty()); -} - -// Check that equal Axis2Placement3ds are merged for StepShape_GeometricCurveSet. -TEST_F(MergeSTEPEntities_Axis2Placement3dProcessorTest, StepGeom_Plane) -{ - // Creating Axis2Placement3ds. - Handle(StepGeom_Axis2Placement3d) anAxis1 = addAxis2Placement3d(); - Handle(StepGeom_Axis2Placement3d) anAxis2 = addAxis2Placement3d(); - - // Creating a plane containing the first Axis2Placement3d. - Handle(StepGeom_Plane) aPlane1 = new StepGeom_Plane; - aPlane1->Init(new TCollection_HAsciiString, anAxis1); - addToModel(aPlane1); - - // Creating a plane containing the second Axis2Placement3d. - Handle(StepGeom_Plane) aPlane2 = new StepGeom_Plane; - aPlane2->Init(new TCollection_HAsciiString, anAxis2); - addToModel(aPlane2); - - // Performing removal of duplicate Axis2Placement3ds. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateAxis2Placement3ds(); - - // Check that one Axis2Placement3d was removed. - EXPECT_EQ(aRemovedEntities.Extent(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(anAxis1) || aRemovedEntities.Contains(anAxis2)); -} - -// Check that equal Axis2Placement3ds are merged for StepRepr_ItemDefinedTransformation. -TEST_F(MergeSTEPEntities_Axis2Placement3dProcessorTest, StepRepr_ItemDefinedTransformation) -{ - // Creating Axis2Placement3ds. - Handle(StepGeom_Axis2Placement3d) anAxis1 = addAxis2Placement3d(); - Handle(StepGeom_Axis2Placement3d) anAxis2 = addAxis2Placement3d(); - Handle(StepGeom_Axis2Placement3d) anAxis3 = addAxis2Placement3d(nullptr, gp_XYZ(1., 1., 1.)); - - // Creating ItemDefinedTransformation containing the first Axis2Placement3d. - Handle(StepRepr_ItemDefinedTransformation) aItem1 = new StepRepr_ItemDefinedTransformation; - aItem1->Init(new TCollection_HAsciiString, new TCollection_HAsciiString, anAxis1, anAxis3); - addToModel(aItem1); - - // Creating ItemDefinedTransformation containing the second Axis2Placement3d. - Handle(StepRepr_ItemDefinedTransformation) aItem2 = new StepRepr_ItemDefinedTransformation; - aItem1->Init(new TCollection_HAsciiString, new TCollection_HAsciiString, anAxis2, anAxis3); - addToModel(aItem2); - - // Performing removal of duplicate Axis2Placement3ds. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateAxis2Placement3ds(); - - // Check that one Axis2Placement3d was removed. - EXPECT_EQ(aRemovedEntities.Extent(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(anAxis1) || aRemovedEntities.Contains(anAxis2)); -} - -// Check that equal Axis2Placement3ds are merged for StepGeom_CylindricalSurface. -TEST_F(MergeSTEPEntities_Axis2Placement3dProcessorTest, StepGeom_CylindricalSurface) -{ - // Creating Axis2Placement3ds. - Handle(StepGeom_Axis2Placement3d) anAxis1 = addAxis2Placement3d(); - Handle(StepGeom_Axis2Placement3d) anAxis2 = addAxis2Placement3d(); - - // Creating a cylindrical surface containing the first Axis2Placement3d. - Handle(StepGeom_CylindricalSurface) aCylindricalSurface1 = new StepGeom_CylindricalSurface; - aCylindricalSurface1->Init(new TCollection_HAsciiString, anAxis1, 1.0); - addToModel(aCylindricalSurface1); - - // Creating a cylindrical surface containing the second Axis2Placement3d. - Handle(StepGeom_CylindricalSurface) aCylindricalSurface2 = new StepGeom_CylindricalSurface; - aCylindricalSurface2->Init(new TCollection_HAsciiString, anAxis2, 1.0); - addToModel(aCylindricalSurface2); - - // Performing removal of duplicate Axis2Placement3ds. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateAxis2Placement3ds(); - - // Check that one Axis2Placement3d was removed. - EXPECT_EQ(aRemovedEntities.Extent(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(anAxis1) || aRemovedEntities.Contains(anAxis2)); -} - -// Check that equal Axis2Placement3ds are merged for StepShape_ShapeRepresentation. -TEST_F(MergeSTEPEntities_Axis2Placement3dProcessorTest, StepShape_ShapeRepresentation) -{ - // Creating Axis2Placement3ds. - Handle(StepGeom_Axis2Placement3d) anAxis1 = addAxis2Placement3d(); - Handle(StepGeom_Axis2Placement3d) anAxis2 = addAxis2Placement3d(); - - // Creating a shape representation containing the first Axis2Placement3d. - Handle(StepRepr_HArray1OfRepresentationItem) aItems1 = - new StepRepr_HArray1OfRepresentationItem(1, 1); - aItems1->SetValue(1, anAxis1); - Handle(StepShape_ShapeRepresentation) aShapeRepresentation1 = new StepShape_ShapeRepresentation; - aShapeRepresentation1->Init(new TCollection_HAsciiString, - aItems1, - new StepRepr_RepresentationContext); - addToModel(aShapeRepresentation1); - - // Creating a shape representation containing the second Axis2Placement3d. - Handle(StepRepr_HArray1OfRepresentationItem) aItems2 = - new StepRepr_HArray1OfRepresentationItem(1, 1); - aItems2->SetValue(1, anAxis2); - Handle(StepShape_ShapeRepresentation) aShapeRepresentation2 = new StepShape_ShapeRepresentation; - aShapeRepresentation2->Init(new TCollection_HAsciiString, - aItems2, - new StepRepr_RepresentationContext); - addToModel(aShapeRepresentation2); - - // Performing removal of duplicate Axis2Placement3ds. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateAxis2Placement3ds(); - - // Check that one Axis2Placement3d was removed. - EXPECT_EQ(aRemovedEntities.Extent(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(anAxis1) || aRemovedEntities.Contains(anAxis2)); -} - -// Check that equal Axis2Placement3ds are merged for StepRepr_ConstructiveGeometryRepresentation. -TEST_F(MergeSTEPEntities_Axis2Placement3dProcessorTest, StepRepr_ConstructiveGeometryRepresentation) -{ - // Creating Axis2Placement3ds. - Handle(StepGeom_Axis2Placement3d) anAxis1 = addAxis2Placement3d(); - Handle(StepGeom_Axis2Placement3d) anAxis2 = addAxis2Placement3d(); - - // Creating a constructive geometry representation containing the first Axis2Placement3d. - Handle(StepRepr_HArray1OfRepresentationItem) aItems1 = - new StepRepr_HArray1OfRepresentationItem(1, 1); - aItems1->SetValue(1, anAxis1); - Handle(StepRepr_ConstructiveGeometryRepresentation) aConstructiveGeometryRepresentation1 = - new StepRepr_ConstructiveGeometryRepresentation; - aConstructiveGeometryRepresentation1->Init(new TCollection_HAsciiString, - aItems1, - new StepRepr_RepresentationContext); - addToModel(aConstructiveGeometryRepresentation1); - - // Creating a constructive geometry representation containing the second Axis2Placement3d. - Handle(StepRepr_HArray1OfRepresentationItem) aItems2 = - new StepRepr_HArray1OfRepresentationItem(1, 1); - aItems2->SetValue(1, anAxis2); - Handle(StepRepr_ConstructiveGeometryRepresentation) aConstructiveGeometryRepresentation2 = - new StepRepr_ConstructiveGeometryRepresentation; - aConstructiveGeometryRepresentation2->Init(new TCollection_HAsciiString, - aItems2, - new StepRepr_RepresentationContext); - addToModel(aConstructiveGeometryRepresentation2); - - // Performing removal of duplicate Axis2Placement3ds. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateAxis2Placement3ds(); - - // Check that one Axis2Placement3d was removed. - EXPECT_EQ(aRemovedEntities.Extent(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(anAxis1) || aRemovedEntities.Contains(anAxis2)); -} - -// Check that equal Axis2Placement3ds are merged for StepGeom_Circle. -TEST_F(MergeSTEPEntities_Axis2Placement3dProcessorTest, StepGeom_Circle) -{ - // Creating Axis2Placement3ds. - Handle(StepGeom_Axis2Placement3d) anAxis1 = addAxis2Placement3d(); - Handle(StepGeom_Axis2Placement3d) anAxis2 = addAxis2Placement3d(); - - // Creating a circle containing the first Axis2Placement3d. - StepGeom_Axis2Placement aSelector1; - aSelector1.SetValue(anAxis1); - Handle(StepGeom_Circle) aCircle1 = new StepGeom_Circle; - aCircle1->Init(new TCollection_HAsciiString, aSelector1, 1.0); - addToModel(aCircle1); - - // Creating a circle containing the second Axis2Placement3d. - StepGeom_Axis2Placement aSelector2; - aSelector2.SetValue(anAxis2); - Handle(StepGeom_Circle) aCircle2 = new StepGeom_Circle; - aCircle2->Init(new TCollection_HAsciiString, aSelector2, 1.0); - addToModel(aCircle2); - - // Performing removal of duplicate Axis2Placement3ds. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateAxis2Placement3ds(); - - // Check that one Axis2Placement3d was removed. - EXPECT_EQ(aRemovedEntities.Extent(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(anAxis1) || aRemovedEntities.Contains(anAxis2)); -} - -// Check that equal Axis2Placement3ds are merged for StepVisual_PresentationLayerAssignment. -TEST_F(MergeSTEPEntities_Axis2Placement3dProcessorTest, StepVisual_PresentationLayerAssignment) -{ - // Creating Axis2Placement3ds. - Handle(StepGeom_Axis2Placement3d) anAxis1 = addAxis2Placement3d(); - Handle(StepGeom_Axis2Placement3d) anAxis2 = addAxis2Placement3d(); - - // Creating a presentation layer assignment containing the first Axis2Placement3d. - Handle(StepVisual_HArray1OfLayeredItem) aAssignedItems1 = - new StepVisual_HArray1OfLayeredItem(1, 1); - StepVisual_LayeredItem aLayeredItem1; - aLayeredItem1.SetValue(anAxis1); - aAssignedItems1->SetValue(1, aLayeredItem1); - Handle(StepVisual_PresentationLayerAssignment) aPresentationLayerAssignment1 = - new StepVisual_PresentationLayerAssignment; - aPresentationLayerAssignment1->Init(new TCollection_HAsciiString, - new TCollection_HAsciiString, - aAssignedItems1); - addToModel(aPresentationLayerAssignment1); - - // Creating a presentation layer assignment containing the second Axis2Placement3d. - Handle(StepVisual_HArray1OfLayeredItem) aAssignedItems2 = - new StepVisual_HArray1OfLayeredItem(1, 1); - StepVisual_LayeredItem aLayeredItem2; - aLayeredItem2.SetValue(anAxis2); - aAssignedItems2->SetValue(1, aLayeredItem2); - Handle(StepVisual_PresentationLayerAssignment) aPresentationLayerAssignment2 = - new StepVisual_PresentationLayerAssignment; - aPresentationLayerAssignment2->Init(new TCollection_HAsciiString, - new TCollection_HAsciiString, - aAssignedItems2); - addToModel(aPresentationLayerAssignment2); - - // Performing removal of duplicate Axis2Placement3ds. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateAxis2Placement3ds(); - - // Check that one Axis2Placement3d was removed. - EXPECT_EQ(aRemovedEntities.Extent(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(anAxis1) || aRemovedEntities.Contains(anAxis2)); -} - -// Check that equal Axis2Placement3ds are merged for StepVisual_StyledItem. -TEST_F(MergeSTEPEntities_Axis2Placement3dProcessorTest, StepVisual_StyledItem) -{ - // Creating Axis2Placement3ds. - Handle(StepGeom_Axis2Placement3d) anAxis1 = addAxis2Placement3d(); - Handle(StepGeom_Axis2Placement3d) anAxis2 = addAxis2Placement3d(); - - // Creating a styled item containing the first Axis2Placement3d. - Handle(StepVisual_StyledItem) aStiledItem1 = new StepVisual_StyledItem; - aStiledItem1->Init(new TCollection_HAsciiString, - new StepVisual_HArray1OfPresentationStyleAssignment(1, 1), - anAxis1); - addToModel(aStiledItem1); - - // Creating a styled item containing the second Axis2Placement3d. - Handle(StepVisual_StyledItem) aStiledItem2 = new StepVisual_StyledItem; - aStiledItem2->Init(new TCollection_HAsciiString, - new StepVisual_HArray1OfPresentationStyleAssignment(1, 1), - anAxis2); - addToModel(aStiledItem2); - - // Performing removal of duplicate Axis2Placement3ds. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateAxis2Placement3ds(); - - // Check that one Axis2Placement3d was removed. - EXPECT_EQ(aRemovedEntities.Extent(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(anAxis1) || aRemovedEntities.Contains(anAxis2)); -} - -// Check that equal Axis2Placement3ds are merged for StepGeom_Ellipse. -TEST_F(MergeSTEPEntities_Axis2Placement3dProcessorTest, StepGeom_Ellipse) -{ - // Creating Axis2Placement3ds. - Handle(StepGeom_Axis2Placement3d) anAxis1 = addAxis2Placement3d(); - Handle(StepGeom_Axis2Placement3d) anAxis2 = addAxis2Placement3d(); - - // Creating an ellipse containing the first Axis2Placement3d. - StepGeom_Axis2Placement aSelector1; - aSelector1.SetValue(anAxis1); - Handle(StepGeom_Ellipse) aEllipse1 = new StepGeom_Ellipse; - aEllipse1->Init(new TCollection_HAsciiString, aSelector1, 1.0, 2.0); - addToModel(aEllipse1); - - // Creating an ellipse containing the second Axis2Placement3d. - StepGeom_Axis2Placement aSelector2; - aSelector2.SetValue(anAxis2); - Handle(StepGeom_Ellipse) aEllipse2 = new StepGeom_Ellipse; - aEllipse2->Init(new TCollection_HAsciiString, aSelector2, 1.0, 2.0); - addToModel(aEllipse2); - - // Performing removal of duplicate Axis2Placement3ds. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateAxis2Placement3ds(); - - // Check that one Axis2Placement3d was removed. - EXPECT_EQ(aRemovedEntities.Extent(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(anAxis1) || aRemovedEntities.Contains(anAxis2)); -} - -// Check that equal Axis2Placement3ds are merged for StepGeom_ConicalSurface. -TEST_F(MergeSTEPEntities_Axis2Placement3dProcessorTest, StepGeom_ConicalSurface) -{ - // Creating Axis2Placement3ds. - Handle(StepGeom_Axis2Placement3d) anAxis1 = addAxis2Placement3d(); - Handle(StepGeom_Axis2Placement3d) anAxis2 = addAxis2Placement3d(); - - // Creating a conical surface containing the first Axis2Placement3d. - Handle(StepGeom_ConicalSurface) aConicalSurface1 = new StepGeom_ConicalSurface; - aConicalSurface1->Init(new TCollection_HAsciiString, anAxis1, 1.0, 1.0); - addToModel(aConicalSurface1); - - // Creating a conical surface containing the second Axis2Placement3d. - Handle(StepGeom_ConicalSurface) aConicalSurface2 = new StepGeom_ConicalSurface; - aConicalSurface2->Init(new TCollection_HAsciiString, anAxis2, 1.0, 1.0); - addToModel(aConicalSurface2); - - // Performing removal of duplicate Axis2Placement3ds. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateAxis2Placement3ds(); - - // Check that one Axis2Placement3d was removed. - EXPECT_EQ(aRemovedEntities.Extent(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(anAxis1) || aRemovedEntities.Contains(anAxis2)); -} - -// Check that equal Axis2Placement3ds are merged for StepGeom_ToroidalSurface. -TEST_F(MergeSTEPEntities_Axis2Placement3dProcessorTest, StepGeom_ToroidalSurface) -{ - // Creating Axis2Placement3ds. - Handle(StepGeom_Axis2Placement3d) anAxis1 = addAxis2Placement3d(); - Handle(StepGeom_Axis2Placement3d) anAxis2 = addAxis2Placement3d(); - - // Creating a toroidal surface containing the first Axis2Placement3d. - Handle(StepGeom_ToroidalSurface) aToroidalSurface1 = new StepGeom_ToroidalSurface; - aToroidalSurface1->Init(new TCollection_HAsciiString, anAxis1, 1.0, 1.0); - addToModel(aToroidalSurface1); - - // Creating a toroidal surface containing the second Axis2Placement3d. - Handle(StepGeom_ToroidalSurface) aToroidalSurface2 = new StepGeom_ToroidalSurface; - aToroidalSurface2->Init(new TCollection_HAsciiString, anAxis2, 1.0, 1.0); - addToModel(aToroidalSurface2); - - // Performing removal of duplicate Axis2Placement3ds. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateAxis2Placement3ds(); - - // Check that one Axis2Placement3d was removed. - EXPECT_EQ(aRemovedEntities.Extent(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(anAxis1) || aRemovedEntities.Contains(anAxis2)); -} - -// Check that equal Axis2Placement3ds are merged for StepShape_AdvancedBrepShapeRepresentation. -TEST_F(MergeSTEPEntities_Axis2Placement3dProcessorTest, StepShape_AdvancedBrepShapeRepresentation) -{ - // Creating Axis2Placement3ds. - Handle(StepGeom_Axis2Placement3d) anAxis1 = addAxis2Placement3d(); - Handle(StepGeom_Axis2Placement3d) anAxis2 = addAxis2Placement3d(); - - // Creating a shape representation containing the first Axis2Placement3d. - Handle(StepRepr_HArray1OfRepresentationItem) aItems1 = - new StepRepr_HArray1OfRepresentationItem(1, 1); - aItems1->SetValue(1, anAxis1); - Handle(StepShape_AdvancedBrepShapeRepresentation) aShapeRepresentation1 = - new StepShape_AdvancedBrepShapeRepresentation; - aShapeRepresentation1->Init(new TCollection_HAsciiString, - aItems1, - new StepRepr_RepresentationContext); - addToModel(aShapeRepresentation1); - - // Creating a shape representation containing the second Axis2Placement3d. - Handle(StepRepr_HArray1OfRepresentationItem) aItems2 = - new StepRepr_HArray1OfRepresentationItem(1, 1); - aItems2->SetValue(1, anAxis2); - Handle(StepShape_AdvancedBrepShapeRepresentation) aShapeRepresentation2 = - new StepShape_AdvancedBrepShapeRepresentation; - aShapeRepresentation2->Init(new TCollection_HAsciiString, - aItems2, - new StepRepr_RepresentationContext); - addToModel(aShapeRepresentation2); - - // Performing removal of duplicate Axis2Placement3ds. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateAxis2Placement3ds(); - - // Check that one Axis2Placement3d was removed. - EXPECT_EQ(aRemovedEntities.Extent(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(anAxis1) || aRemovedEntities.Contains(anAxis2)); -} - -// Check that equal Axis2Placement3ds are merged for StepGeom_SphericalSurface. -TEST_F(MergeSTEPEntities_Axis2Placement3dProcessorTest, StepGeom_SphericalSurface) -{ - // Creating Axis2Placement3ds. - Handle(StepGeom_Axis2Placement3d) anAxis1 = addAxis2Placement3d(); - Handle(StepGeom_Axis2Placement3d) anAxis2 = addAxis2Placement3d(); - - // Creating a spherical surface containing the first Axis2Placement3d. - Handle(StepGeom_SphericalSurface) aSphericalSurface1 = new StepGeom_SphericalSurface; - aSphericalSurface1->Init(new TCollection_HAsciiString, anAxis1, 1.0); - addToModel(aSphericalSurface1); - - // Creating a spherical surface containing the second Axis2Placement3d. - Handle(StepGeom_SphericalSurface) aSphericalSurface2 = new StepGeom_SphericalSurface; - aSphericalSurface2->Init(new TCollection_HAsciiString, anAxis2, 1.0); - addToModel(aSphericalSurface2); - - // Performing removal of duplicate Axis2Placement3ds. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateAxis2Placement3ds(); - - // Check that one Axis2Placement3d was removed. - EXPECT_EQ(aRemovedEntities.Extent(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(anAxis1) || aRemovedEntities.Contains(anAxis2)); -} diff --git a/src/DataExchange/TKDESTEP/GTests/MergeSTEPEntities_BaseTestFixture.hxx b/src/DataExchange/TKDESTEP/GTests/MergeSTEPEntities_BaseTestFixture.hxx deleted file mode 100644 index f0d38929ab..0000000000 --- a/src/DataExchange/TKDESTEP/GTests/MergeSTEPEntities_BaseTestFixture.hxx +++ /dev/null @@ -1,194 +0,0 @@ -// 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. - -#ifndef _MergeSTEPEntities_BaseTestFixture_HeaderFile -#define _MergeSTEPEntities_BaseTestFixture_HeaderFile - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -class MergeSTEPEntities_BaseTestFixture : public testing::Test -{ -protected: - // Initialize the work session and model. - MergeSTEPEntities_BaseTestFixture() - : myWS() - { - STEPControl_Controller::Init(); - myWS = new XSControl_WorkSession; - myWS->SelectNorm("STEP"); - myWS->SetModel(myWS->NormAdaptor()->NewModel()); - } - - // Add a Cartesian point to the model. - // @param theName the name of the Cartesian point. - // @param thePoint the coordinates of the Cartesian point. - // @return the added Cartesian point. - Handle(StepGeom_CartesianPoint) addCartesianPoint(const char* theName = nullptr, - const gp_XYZ& thePoint = gp_XYZ(0., - 0., - 0.)) const - { - const Handle(StepGeom_CartesianPoint) aCartesianPoint = new StepGeom_CartesianPoint; - const Handle(TCollection_HAsciiString) aName = - theName ? new TCollection_HAsciiString(theName) : new TCollection_HAsciiString(); - aCartesianPoint->Init3D(aName, thePoint.X(), thePoint.Y(), thePoint.Z()); - myWS->Model()->AddWithRefs(aCartesianPoint); - return aCartesianPoint; - } - - // Add a direction to the model. - // @param theName the name of the direction. - // @param theDirection the direction ratios. - // @return the added direction. - Handle(StepGeom_Direction) addDirection(const char* theName = nullptr, - const gp_XYZ& theDirection = gp_XYZ(0., 0., 1.)) const - { - const Handle(StepGeom_Direction) aDirection = new StepGeom_Direction; - const Handle(TCollection_HAsciiString) aName = - theName ? new TCollection_HAsciiString(theName) : new TCollection_HAsciiString(); - Handle(TColStd_HArray1OfReal) aDirectionRatios = new TColStd_HArray1OfReal(1, 3); - aDirectionRatios->SetValue(1, theDirection.X()); - aDirectionRatios->SetValue(2, theDirection.Y()); - aDirectionRatios->SetValue(3, theDirection.Z()); - aDirection->Init(aName, aDirectionRatios); - myWS->Model()->AddWithRefs(aDirection); - return aDirection; - } - - // Add a vector to the model. - // @param theName the name of the vector. - // @param theOrientation the orientation of the vector. - // @param aMagnitude the magnitude of the vector. - // @return the added vector. - Handle(StepGeom_Vector) addVector(const char* theName = nullptr, - const gp_XYZ& theOrientation = gp_XYZ(0., 0., 1.), - const double aMagnitude = 1.) const - { - const Handle(StepGeom_Vector) aVector = new StepGeom_Vector; - const Handle(TCollection_HAsciiString) aName = - theName ? new TCollection_HAsciiString(theName) : new TCollection_HAsciiString(); - aVector->Init(aName, addDirection(nullptr, theOrientation), aMagnitude); - myWS->Model()->AddWithRefs(aVector); - return aVector; - } - - // Add an Axis2Placement3d to the model. - // @param theName the name of the Axis2Placement3d. - // @param theLocation the location of the Axis2Placement3d. - // @param theAxis the axis of the Axis2Placement3d. - // @param theRefDirection the reference direction of the Axis2Placement3d. - // @return the added Axis2Placement3d. - Handle(StepGeom_Axis2Placement3d) addAxis2Placement3d( - const char* theName = nullptr, - const gp_XYZ& theLocation = gp_XYZ(0., 0., 0.), - const gp_XYZ& theAxis = gp_XYZ(0., 0., 1.), - const gp_XYZ& theRefDirection = gp_XYZ(0., 1., 0.)) const - { - const Handle(StepGeom_Axis2Placement3d) aAxis2Placement3d = new StepGeom_Axis2Placement3d; - const Handle(TCollection_HAsciiString) aName = - theName ? new TCollection_HAsciiString(theName) : new TCollection_HAsciiString(); - aAxis2Placement3d->Init(aName, - addCartesianPoint(nullptr, theLocation), - true, - addDirection(nullptr, theAxis), - true, - addDirection(nullptr, theRefDirection)); - myWS->Model()->AddWithRefs(aAxis2Placement3d); - return aAxis2Placement3d; - } - - // Add a line to the model. - // @param theName the name of the line. - // @param theLocation the location of the line. - // @param theOrientation the orientation of the line vector. - // @param theMagnitude the magnitude of the line vector. - // @return the added line. - Handle(StepGeom_Line) addLine(const char* theName = nullptr, - const gp_XYZ& theLocation = gp_XYZ(0., 0., 0.), - const gp_XYZ& theOrientation = gp_XYZ(0., 0., 1.), - const double aMagnitude = 1.) const - { - const Handle(StepGeom_Line) aLine = new StepGeom_Line; - const Handle(TCollection_HAsciiString) aName = - theName ? new TCollection_HAsciiString(theName) : new TCollection_HAsciiString(); - aLine->Init(aName, - addCartesianPoint(nullptr, theLocation), - addVector(nullptr, theOrientation, aMagnitude)); - myWS->Model()->AddWithRefs(aLine); - return aLine; - } - - // Add a circle to the model. - // @param theName the name of the circle. - // @param theLocation the location of the circle. - // @param theAxis the axis of the circle. - // @param theRefDirection the reference direction of the circle. - // @param theRadius the radius of the circle. - // @return the added circle. - Handle(StepGeom_Circle) addCircle(const char* theName = nullptr, - const gp_XYZ& theLocation = gp_XYZ(0., 0., 0.), - const gp_XYZ& theAxis = gp_XYZ(0., 0., 1.), - const gp_XYZ& theRefDirection = gp_XYZ(0., 1., 0.), - const double theRadius = 1.) const - { - const Handle(StepGeom_Circle) aCircle = new StepGeom_Circle; - const Handle(TCollection_HAsciiString) aName = - theName ? new TCollection_HAsciiString(theName) : new TCollection_HAsciiString(); - StepGeom_Axis2Placement aSelector; - aSelector.SetValue(addAxis2Placement3d(nullptr, theLocation, theAxis, theRefDirection)); - aCircle->Init(aName, aSelector, theRadius); - myWS->Model()->AddWithRefs(aCircle); - return aCircle; - } - - // Add a plane to the model. - // @param theName the name of the plane. - // @param theLocation the location of the plane. - // @param theAxis the axis of the plane. - // @param theRefDirection the reference direction of the plane. - // @return the added plane. - Handle(StepGeom_Plane) addPlane(const char* theName = nullptr, - const gp_XYZ& theLocation = gp_XYZ(0., 0., 0.), - const gp_XYZ& theAxis = gp_XYZ(0., 0., 1.), - const gp_XYZ& theRefDirection = gp_XYZ(0., 1., 0.)) const - { - const Handle(StepGeom_Plane) aPlane = new StepGeom_Plane; - const Handle(TCollection_HAsciiString) aName = - theName ? new TCollection_HAsciiString(theName) : new TCollection_HAsciiString(); - aPlane->Init(aName, addAxis2Placement3d(nullptr, theLocation, theAxis, theRefDirection)); - myWS->Model()->AddWithRefs(aPlane); - return aPlane; - } - - // Add an entity to the model. - // @param theEntity the entity to add. - void addToModel(const Handle(Standard_Transient)& theEntity) const - { - myWS->Model()->AddWithRefs(theEntity); - } - -protected: - Handle(XSControl_WorkSession) myWS; -}; - -#endif // _MergeSTEPEntities_BaseTestFixture_HeaderFile diff --git a/src/DataExchange/TKDESTEP/GTests/MergeSTEPEntities_CartesianPointProcessor_Test.cxx b/src/DataExchange/TKDESTEP/GTests/MergeSTEPEntities_CartesianPointProcessor_Test.cxx deleted file mode 100644 index 0a45609828..0000000000 --- a/src/DataExchange/TKDESTEP/GTests/MergeSTEPEntities_CartesianPointProcessor_Test.cxx +++ /dev/null @@ -1,594 +0,0 @@ -// 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 "MergeSTEPEntities_BaseTestFixture.hxx" - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -class MergeSTEPEntities_CartesianPointProcessorTest : public MergeSTEPEntities_BaseTestFixture -{ -protected: - // Perform removal of duplicate Cartesian points. - TColStd_MapOfTransient replaceDuplicateCartesianPoints() - { - MergeSTEPEntities_CartesianPointProcessor aProcessor(myWS); - for (Standard_Integer anIndex = 1; anIndex <= myWS->Model()->NbEntities(); ++anIndex) - { - aProcessor.ProcessEntity(myWS->Model()->Value(anIndex)); - } - - TColStd_MapOfTransient aRemovedEntities; - aProcessor.Perform(aRemovedEntities); - return aRemovedEntities; - } -}; - -// Check that points with the same coordinates and different names are not merged. -TEST_F(MergeSTEPEntities_CartesianPointProcessorTest, DifferentNames) -{ - // Creating Cartesian points. - Handle(StepGeom_CartesianPoint) aPt1 = addCartesianPoint("FirstPt"); - Handle(StepGeom_CartesianPoint) aPt2 = addCartesianPoint("SecondPt"); - - // Creating direction. - Handle(TColStd_HArray1OfReal) aDirCoords = new TColStd_HArray1OfReal(1, 3); - aDirCoords->SetValue(1, 0.); - aDirCoords->SetValue(2, 0.); - aDirCoords->SetValue(3, 1.); - Handle(StepGeom_Direction) aDir = new StepGeom_Direction; - aDir->Init(new TCollection_HAsciiString, aDirCoords); - addToModel(aDir); - - // Creating axis containing the first Cartesian point. - Handle(StepGeom_Axis2Placement3d) aFirstAxis = new StepGeom_Axis2Placement3d; - aFirstAxis - ->Init(new TCollection_HAsciiString, aPt1, Standard_True, aDir, Standard_False, nullptr); - addToModel(aFirstAxis); - - // Creating axis containing the second Cartesian point. - Handle(StepGeom_Axis2Placement3d) aSecondAxis = new StepGeom_Axis2Placement3d; - aSecondAxis - ->Init(new TCollection_HAsciiString, aPt2, Standard_True, aDir, Standard_False, nullptr); - addToModel(aSecondAxis); - - // Performing removal of duplicate Cartesian points. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateCartesianPoints(); - - // Check that nothing was removed. - EXPECT_TRUE(aRemovedEntities.IsEmpty()); -} - -// Check that points with the same coordinates and same names are -// merged for StepGeom_Axis2Placement3d. -TEST_F(MergeSTEPEntities_CartesianPointProcessorTest, StepGeom_Axis2Placement3d) -{ - // Creating Cartesian points. - Handle(StepGeom_CartesianPoint) aPt1 = addCartesianPoint(); - Handle(StepGeom_CartesianPoint) aPt2 = addCartesianPoint(); - - // Creating direction. - Handle(TColStd_HArray1OfReal) aDirCoords = new TColStd_HArray1OfReal(1, 3); - aDirCoords->SetValue(1, 0.); - aDirCoords->SetValue(2, 0.); - aDirCoords->SetValue(3, 1.); - Handle(StepGeom_Direction) aDir = new StepGeom_Direction; - aDir->Init(new TCollection_HAsciiString, aDirCoords); - addToModel(aDir); - - // Creating axis containing the first Cartesian point. - Handle(StepGeom_Axis2Placement3d) aFirstAxis = new StepGeom_Axis2Placement3d; - aFirstAxis - ->Init(new TCollection_HAsciiString, aPt1, Standard_True, aDir, Standard_False, nullptr); - addToModel(aFirstAxis); - - // Creating axis containing the second Cartesian point. - Handle(StepGeom_Axis2Placement3d) aSecondAxis = new StepGeom_Axis2Placement3d; - aSecondAxis - ->Init(new TCollection_HAsciiString, aPt2, Standard_True, aDir, Standard_False, nullptr); - addToModel(aSecondAxis); - - // Performing removal of duplicate Cartesian points. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateCartesianPoints(); - - // Check that duplicate was removed. - EXPECT_EQ(aRemovedEntities.Size(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(aPt1) || aRemovedEntities.Contains(aPt2)); -} - -// Check that points with the same coordinates and same names are merged -// for StepShape_VertexPoint. -TEST_F(MergeSTEPEntities_CartesianPointProcessorTest, StepShape_VertexPoint) -{ - // Creating Cartesian points. - Handle(StepGeom_CartesianPoint) aPt1 = addCartesianPoint(); - Handle(StepGeom_CartesianPoint) aPt2 = addCartesianPoint(); - - // Creating vertex containing the first Cartesian point. - Handle(StepShape_VertexPoint) aFirstVertex = new StepShape_VertexPoint; - aFirstVertex->Init(new TCollection_HAsciiString, aPt1); - addToModel(aFirstVertex); - - // Creating vertex containing the second Cartesian point. - Handle(StepShape_VertexPoint) aSecondVertex = new StepShape_VertexPoint; - aSecondVertex->Init(new TCollection_HAsciiString, aPt2); - addToModel(aSecondVertex); - - // Performing removal of duplicate Cartesian points. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateCartesianPoints(); - - // Check that duplicate was removed. - EXPECT_EQ(aRemovedEntities.Size(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(aPt1) || aRemovedEntities.Contains(aPt2)); -} - -// Check that points with the same coordinates and same names are merged -// for StepShape_GeometricCurveSet. -TEST_F(MergeSTEPEntities_CartesianPointProcessorTest, StepShape_GeometricCurveSet) -{ - // Creating Cartesian points. - Handle(StepGeom_CartesianPoint) aPt1 = addCartesianPoint(); - Handle(StepGeom_CartesianPoint) aPt2 = addCartesianPoint(); - - // Creating curve set containing the first Cartesian point. - Handle(StepShape_HArray1OfGeometricSetSelect) aFirstElements = - new StepShape_HArray1OfGeometricSetSelect(1, 1); - StepShape_GeometricSetSelect aFirstSelect; - aFirstSelect.SetValue(aPt1); - aFirstElements->SetValue(1, aFirstSelect); - addToModel(aFirstElements); - Handle(StepShape_GeometricCurveSet) aFirstCurveSet = new StepShape_GeometricCurveSet; - aFirstCurveSet->Init(new TCollection_HAsciiString, aFirstElements); - addToModel(aFirstCurveSet); - - // Creating curve set containing the second Cartesian point. - Handle(StepShape_HArray1OfGeometricSetSelect) aSecondElements = - new StepShape_HArray1OfGeometricSetSelect(1, 1); - StepShape_GeometricSetSelect aSecondSelect; - aSecondSelect.SetValue(aPt2); - aSecondElements->SetValue(1, aSecondSelect); - addToModel(aSecondElements); - Handle(StepShape_GeometricCurveSet) aSecondCurveSet = new StepShape_GeometricCurveSet; - aSecondCurveSet->Init(new TCollection_HAsciiString, aSecondElements); - addToModel(aSecondCurveSet); - - // Performing removal of duplicate Cartesian points. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateCartesianPoints(); - - // Check that duplicate was removed. - EXPECT_EQ(aRemovedEntities.Size(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(aPt1) || aRemovedEntities.Contains(aPt2)); -} - -// Check that points with the same coordinates and same names are merged -// for StepVisual_PresentationLayerAssignment. -TEST_F(MergeSTEPEntities_CartesianPointProcessorTest, StepVisual_PresentationLayerAssignment) -{ - // Creating Cartesian points. - Handle(StepGeom_CartesianPoint) aPt1 = addCartesianPoint(); - Handle(StepGeom_CartesianPoint) aPt2 = addCartesianPoint(); - - // Creating presentation layer assignment containing the first Cartesian point. - Handle(StepVisual_HArray1OfLayeredItem) aFirstAssignedItems = - new StepVisual_HArray1OfLayeredItem(1, 1); - StepVisual_LayeredItem aFirstLayeredItem; - aFirstLayeredItem.SetValue(aPt1); - aFirstAssignedItems->SetValue(1, aFirstLayeredItem); - addToModel(aFirstAssignedItems); - Handle(StepVisual_PresentationLayerAssignment) aFirstAssignment = - new StepVisual_PresentationLayerAssignment; - aFirstAssignment->Init(new TCollection_HAsciiString, - new TCollection_HAsciiString, - aFirstAssignedItems); - addToModel(aFirstAssignment); - - // Creating presentation layer assignment containing the second Cartesian point. - Handle(StepVisual_HArray1OfLayeredItem) aSecondAssignedItems = - new StepVisual_HArray1OfLayeredItem(1, 1); - StepVisual_LayeredItem aSecondLayeredItem; - aSecondLayeredItem.SetValue(aPt2); - aSecondAssignedItems->SetValue(1, aSecondLayeredItem); - addToModel(aSecondAssignedItems); - Handle(StepVisual_PresentationLayerAssignment) aSecondAssignment = - new StepVisual_PresentationLayerAssignment; - aSecondAssignment->Init(new TCollection_HAsciiString, - new TCollection_HAsciiString, - aSecondAssignedItems); - addToModel(aSecondAssignment); - - // Performing removal of duplicate Cartesian points. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateCartesianPoints(); - - // Check that duplicate was removed. - EXPECT_EQ(aRemovedEntities.Size(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(aPt1) || aRemovedEntities.Contains(aPt2)); -} - -// Check that points with the same coordinates and same names are merged -// for StepVisual_StyledItem. -TEST_F(MergeSTEPEntities_CartesianPointProcessorTest, StepVisual_StyledItem) -{ - // Creating Cartesian points. - Handle(StepGeom_CartesianPoint) aPt1 = addCartesianPoint(); - Handle(StepGeom_CartesianPoint) aPt2 = addCartesianPoint(); - - // Creating styled item containing the first Cartesian point. - Handle(StepVisual_HArray1OfPresentationStyleAssignment) aFirstAssignedItems = - new StepVisual_HArray1OfPresentationStyleAssignment(1, 1); - Handle(StepVisual_StyledItem) aFirstStyledItem = new StepVisual_StyledItem; - aFirstStyledItem->Init(new TCollection_HAsciiString, aFirstAssignedItems, aPt1); - addToModel(aFirstStyledItem); - - // Creating styled item containing the second Cartesian point. - Handle(StepVisual_HArray1OfPresentationStyleAssignment) aSecondAssignedItems = - new StepVisual_HArray1OfPresentationStyleAssignment(1, 1); - Handle(StepVisual_StyledItem) aSecondStyledItem = new StepVisual_StyledItem; - aSecondStyledItem->Init(new TCollection_HAsciiString, aSecondAssignedItems, aPt2); - addToModel(aSecondStyledItem); - - // Performing removal of duplicate Cartesian points. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateCartesianPoints(); - - // Check that duplicate was removed. - EXPECT_EQ(aRemovedEntities.Size(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(aPt1) || aRemovedEntities.Contains(aPt2)); -} - -// Check that points with the same coordinates and same names are merged -// for StepGeom_BSplineCurveWithKnots. -TEST_F(MergeSTEPEntities_CartesianPointProcessorTest, StepGeom_BSplineCurveWithKnots) -{ - // Creating Cartesian points. - Handle(StepGeom_CartesianPoint) aPt1 = addCartesianPoint(); - Handle(StepGeom_CartesianPoint) aPt2 = addCartesianPoint(); - - // Creating curve containing the first Cartesian point. - Handle(StepGeom_HArray1OfCartesianPoint) aFirstControlPoints = - new StepGeom_HArray1OfCartesianPoint(1, 1); - aFirstControlPoints->SetValue(1, aPt1); - addToModel(aFirstControlPoints); - Handle(StepGeom_BSplineCurveWithKnots) aFirstCurve = new StepGeom_BSplineCurveWithKnots; - aFirstCurve->Init(new TCollection_HAsciiString, - 1, - aFirstControlPoints, - StepGeom_bscfUnspecified, - StepData_LUnknown, - StepData_LUnknown, - new TColStd_HArray1OfInteger, - new TColStd_HArray1OfReal, - StepGeom_ktUnspecified); - addToModel(aFirstCurve); - - // Creating curve containing the second Cartesian point. - Handle(StepGeom_HArray1OfCartesianPoint) aSecondControlPoints = - new StepGeom_HArray1OfCartesianPoint(1, 1); - aSecondControlPoints->SetValue(1, aPt2); - addToModel(aSecondControlPoints); - Handle(StepGeom_BSplineCurveWithKnots) aSecondCurve = new StepGeom_BSplineCurveWithKnots; - aSecondCurve->Init(new TCollection_HAsciiString, - 1, - aSecondControlPoints, - StepGeom_bscfUnspecified, - StepData_LUnknown, - StepData_LUnknown, - new TColStd_HArray1OfInteger, - new TColStd_HArray1OfReal, - StepGeom_ktUnspecified); - addToModel(aSecondCurve); - - // Performing removal of duplicate Cartesian points. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateCartesianPoints(); - - // Check that duplicate was removed. - EXPECT_EQ(aRemovedEntities.Size(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(aPt1) || aRemovedEntities.Contains(aPt2)); -} - -// Check that points with the same coordinates and same names are merged -// for StepGeom_Line. -TEST_F(MergeSTEPEntities_CartesianPointProcessorTest, StepGeom_Line) -{ - // Creating Cartesian points. - Handle(StepGeom_CartesianPoint) aPt1 = addCartesianPoint(); - Handle(StepGeom_CartesianPoint) aPt2 = addCartesianPoint(); - - // Creating line containing the first Cartesian point. - Handle(StepGeom_Line) aFirstLine = new StepGeom_Line; - aFirstLine->Init(new TCollection_HAsciiString, aPt1, new StepGeom_Vector); - addToModel(aFirstLine); - - // Creating line containing the second Cartesian point. - Handle(StepGeom_Line) aSecondLine = new StepGeom_Line; - aSecondLine->Init(new TCollection_HAsciiString, aPt2, new StepGeom_Vector); - addToModel(aSecondLine); - - // Performing removal of duplicate Cartesian points. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateCartesianPoints(); - - // Check that duplicate was removed. - EXPECT_EQ(aRemovedEntities.Size(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(aPt1) || aRemovedEntities.Contains(aPt2)); -} - -// Check that points with the same coordinates and same names are merged -// for StepGeom_BSplineSurfaceWithKnots. -TEST_F(MergeSTEPEntities_CartesianPointProcessorTest, StepGeom_BSplineSurfaceWithKnots) -{ - // Creating Cartesian points. - Handle(StepGeom_CartesianPoint) aPt1 = addCartesianPoint(); - Handle(StepGeom_CartesianPoint) aPt2 = addCartesianPoint(); - - // Creating surface containing the first Cartesian point. - Handle(StepGeom_HArray2OfCartesianPoint) aFirstControlPoints = - new StepGeom_HArray2OfCartesianPoint(1, 1, 1, 1); - aFirstControlPoints->SetValue(1, 1, aPt1); - addToModel(aFirstControlPoints); - Handle(StepGeom_BSplineSurfaceWithKnots) aFirstSurface = new StepGeom_BSplineSurfaceWithKnots; - aFirstSurface->Init(new TCollection_HAsciiString, - 1, - 1, - aFirstControlPoints, - StepGeom_bssfUnspecified, - StepData_LUnknown, - StepData_LUnknown, - StepData_LUnknown, - new TColStd_HArray1OfInteger, - new TColStd_HArray1OfInteger, - new TColStd_HArray1OfReal, - new TColStd_HArray1OfReal, - StepGeom_ktUnspecified); - addToModel(aFirstSurface); - - // Creating surface containing the second Cartesian point. - Handle(StepGeom_HArray2OfCartesianPoint) aSecondControlPoints = - new StepGeom_HArray2OfCartesianPoint(1, 1, 1, 1); - aSecondControlPoints->SetValue(1, 1, aPt2); - addToModel(aSecondControlPoints); - Handle(StepGeom_BSplineSurfaceWithKnots) aSecondSurface = new StepGeom_BSplineSurfaceWithKnots; - aSecondSurface->Init(new TCollection_HAsciiString, - 1, - 1, - aSecondControlPoints, - StepGeom_bssfUnspecified, - StepData_LUnknown, - StepData_LUnknown, - StepData_LUnknown, - new TColStd_HArray1OfInteger, - new TColStd_HArray1OfInteger, - new TColStd_HArray1OfReal, - new TColStd_HArray1OfReal, - StepGeom_ktUnspecified); - addToModel(aSecondSurface); - - // Performing removal of duplicate Cartesian points. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateCartesianPoints(); - - // Check that duplicate was removed. - EXPECT_EQ(aRemovedEntities.Size(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(aPt1) || aRemovedEntities.Contains(aPt2)); -} - -// Check that points with the same coordinates and same names are merged -// for StepGeom_Axis1Placement. -TEST_F(MergeSTEPEntities_CartesianPointProcessorTest, StepGeom_Axis1Placement) -{ - // Creating Cartesian points. - Handle(StepGeom_CartesianPoint) aPt1 = addCartesianPoint(); - Handle(StepGeom_CartesianPoint) aPt2 = addCartesianPoint(); - - // Creating axis containing the first Cartesian point. - Handle(StepGeom_Axis1Placement) aFirstAxis = new StepGeom_Axis1Placement; - aFirstAxis->Init(new TCollection_HAsciiString, aPt1, false, new StepGeom_Direction); - addToModel(aFirstAxis); - - // Creating axis containing the second Cartesian point. - Handle(StepGeom_Axis1Placement) aSecondAxis = new StepGeom_Axis1Placement; - aSecondAxis->Init(new TCollection_HAsciiString, aPt2, false, new StepGeom_Direction); - addToModel(aSecondAxis); - - // Performing removal of duplicate Cartesian points. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateCartesianPoints(); - - // Check that duplicate was removed. - EXPECT_EQ(aRemovedEntities.Size(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(aPt1) || aRemovedEntities.Contains(aPt2)); -} - -// Check that points with the same coordinates and same names are merged -// for StepRepr_Representation. -TEST_F(MergeSTEPEntities_CartesianPointProcessorTest, StepRepr_Representation) -{ - // Creating Cartesian points. - Handle(StepGeom_CartesianPoint) aPt1 = addCartesianPoint(); - Handle(StepGeom_CartesianPoint) aPt2 = addCartesianPoint(); - - // Creating representation containing the first Cartesian point. - Handle(StepRepr_HArray1OfRepresentationItem) aFirstItems = - new StepRepr_HArray1OfRepresentationItem(1, 1); - aFirstItems->SetValue(1, aPt1); - Handle(StepRepr_Representation) aFirstRepresentation = new StepRepr_Representation; - aFirstRepresentation->Init(new TCollection_HAsciiString, - aFirstItems, - new StepRepr_RepresentationContext); - addToModel(aFirstRepresentation); - - // Creating representation containing the second Cartesian point. - Handle(StepRepr_HArray1OfRepresentationItem) aSecondItems = - new StepRepr_HArray1OfRepresentationItem(1, 1); - aSecondItems->SetValue(1, aPt2); - Handle(StepRepr_Representation) aSecondRepresentation = new StepRepr_Representation; - aSecondRepresentation->Init(new TCollection_HAsciiString, - aSecondItems, - new StepRepr_RepresentationContext); - addToModel(aSecondRepresentation); - - // Performing removal of duplicate Cartesian points. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateCartesianPoints(); - - // Check that duplicate was removed. - EXPECT_EQ(aRemovedEntities.Size(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(aPt1) || aRemovedEntities.Contains(aPt2)); -} - -// Check that points with the same coordinates and same names are merged -// for StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve. -TEST_F(MergeSTEPEntities_CartesianPointProcessorTest, - StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve) -{ - // Creating Cartesian points. - Handle(StepGeom_CartesianPoint) aPt1 = addCartesianPoint(); - Handle(StepGeom_CartesianPoint) aPt2 = addCartesianPoint(); - - // Creating curve containing the first Cartesian point. - Handle(StepGeom_HArray1OfCartesianPoint) aFirstControlPoints = - new StepGeom_HArray1OfCartesianPoint(1, 1); - aFirstControlPoints->SetValue(1, aPt1); - addToModel(aFirstControlPoints); - Handle(StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve) aFirstCurve = - new StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve; - aFirstCurve->Init(new TCollection_HAsciiString, - 1, - aFirstControlPoints, - StepGeom_bscfUnspecified, - StepData_LUnknown, - StepData_LUnknown, - new TColStd_HArray1OfInteger, - new TColStd_HArray1OfReal, - StepGeom_ktUnspecified, - new TColStd_HArray1OfReal); - addToModel(aFirstCurve); - - // Creating curve containing the second Cartesian point. - Handle(StepGeom_HArray1OfCartesianPoint) aSecondControlPoints = - new StepGeom_HArray1OfCartesianPoint(1, 1); - aSecondControlPoints->SetValue(1, aPt2); - addToModel(aSecondControlPoints); - Handle(StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve) aSecondCurve = - new StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve; - aSecondCurve->Init(new TCollection_HAsciiString, - 1, - aSecondControlPoints, - StepGeom_bscfUnspecified, - StepData_LUnknown, - StepData_LUnknown, - new TColStd_HArray1OfInteger, - new TColStd_HArray1OfReal, - StepGeom_ktUnspecified, - new TColStd_HArray1OfReal); - addToModel(aSecondCurve); - - // Performing removal of duplicate Cartesian points. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateCartesianPoints(); - - // Check that duplicate was removed. - EXPECT_EQ(aRemovedEntities.Size(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(aPt1) || aRemovedEntities.Contains(aPt2)); -} - -// Check that points with the same coordinates and same names are merged -// for StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface. -TEST_F(MergeSTEPEntities_CartesianPointProcessorTest, - StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface) -{ - // Creating Cartesian points. - Handle(StepGeom_CartesianPoint) aPt1 = addCartesianPoint(); - Handle(StepGeom_CartesianPoint) aPt2 = addCartesianPoint(); - - // Creating surface containing the first Cartesian point. - Handle(StepGeom_HArray2OfCartesianPoint) aFirstControlPoints = - new StepGeom_HArray2OfCartesianPoint(1, 1, 1, 1); - aFirstControlPoints->SetValue(1, 1, aPt1); - addToModel(aFirstControlPoints); - Handle(StepGeom_BSplineSurfaceWithKnots) aFirstBSSWN = new StepGeom_BSplineSurfaceWithKnots; - aFirstBSSWN->Init(new TCollection_HAsciiString, - 1, - 1, - aFirstControlPoints, - StepGeom_bssfUnspecified, - StepData_LUnknown, - StepData_LUnknown, - StepData_LUnknown, - new TColStd_HArray1OfInteger, - new TColStd_HArray1OfInteger, - new TColStd_HArray1OfReal, - new TColStd_HArray1OfReal, - StepGeom_ktUnspecified); - addToModel(aFirstBSSWN); - Handle(StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface) aFirstSurface = - new StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface; - aFirstSurface->Init(new TCollection_HAsciiString, - 1, - 1, - aFirstControlPoints, - StepGeom_bssfUnspecified, - StepData_LUnknown, - StepData_LUnknown, - StepData_LUnknown, - aFirstBSSWN, - new StepGeom_RationalBSplineSurface); - addToModel(aFirstSurface); - - // Creating surface containing the second Cartesian point. - Handle(StepGeom_HArray2OfCartesianPoint) aSecondControlPoints = - new StepGeom_HArray2OfCartesianPoint(1, 1, 1, 1); - aSecondControlPoints->SetValue(1, 1, aPt2); - addToModel(aSecondControlPoints); - Handle(StepGeom_BSplineSurfaceWithKnots) aSecondBSSWN = new StepGeom_BSplineSurfaceWithKnots; - aSecondBSSWN->Init(new TCollection_HAsciiString, - 1, - 1, - aSecondControlPoints, - StepGeom_bssfUnspecified, - StepData_LUnknown, - StepData_LUnknown, - StepData_LUnknown, - new TColStd_HArray1OfInteger, - new TColStd_HArray1OfInteger, - new TColStd_HArray1OfReal, - new TColStd_HArray1OfReal, - StepGeom_ktUnspecified); - addToModel(aSecondBSSWN); - Handle(StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface) aSecondSurface = - new StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface; - aSecondSurface->Init(new TCollection_HAsciiString, - 1, - 1, - aSecondControlPoints, - StepGeom_bssfUnspecified, - StepData_LUnknown, - StepData_LUnknown, - StepData_LUnknown, - new StepGeom_BSplineSurfaceWithKnots, - new StepGeom_RationalBSplineSurface); - - // Performing removal of duplicate Cartesian points. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateCartesianPoints(); - - // Check that duplicate was removed. - EXPECT_EQ(aRemovedEntities.Size(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(aPt1) || aRemovedEntities.Contains(aPt2)); -} diff --git a/src/DataExchange/TKDESTEP/GTests/MergeSTEPEntities_CircleProcessor_Test.cxx b/src/DataExchange/TKDESTEP/GTests/MergeSTEPEntities_CircleProcessor_Test.cxx deleted file mode 100644 index 4d8e3d9e87..0000000000 --- a/src/DataExchange/TKDESTEP/GTests/MergeSTEPEntities_CircleProcessor_Test.cxx +++ /dev/null @@ -1,165 +0,0 @@ -// 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 "MergeSTEPEntities_BaseTestFixture.hxx" - -#include - -#include -#include -#include - -class MergeSTEPEntities_CircleProcessorTest : public MergeSTEPEntities_BaseTestFixture -{ -protected: - //! Perform removal of duplicate entities. - TColStd_MapOfTransient replaceDuplicateCircles() - { - MergeSTEPEntities_CircleProcessor aProcessor(myWS); - for (Standard_Integer anIndex = 1; anIndex <= myWS->Model()->NbEntities(); ++anIndex) - { - aProcessor.ProcessEntity(myWS->Model()->Value(anIndex)); - } - - TColStd_MapOfTransient aRemovedEntities; - aProcessor.Perform(aRemovedEntities); - return aRemovedEntities; - } -}; - -// Check that Circles with the same coordinates and different names are not merged. -TEST_F(MergeSTEPEntities_CircleProcessorTest, DifferentNames) -{ - // Creating Circles. - Handle(StepGeom_Circle) aCircle1 = addCircle("Circle1"); - Handle(StepGeom_Circle) aCircle2 = addCircle("Circle2"); - - // Creating EdgeCurve containing the first Circle. - Handle(StepShape_EdgeCurve) aFirstEdgeCurve = new StepShape_EdgeCurve; - aFirstEdgeCurve->Init(new TCollection_HAsciiString, - new StepShape_Vertex, - new StepShape_Vertex, - aCircle1, - Standard_True); - addToModel(aFirstEdgeCurve); - - // Creating EdgeCurve containing the second Circle. - Handle(StepShape_EdgeCurve) aSecondEdgeCurve = new StepShape_EdgeCurve; - aSecondEdgeCurve->Init(new TCollection_HAsciiString, - new StepShape_Vertex, - new StepShape_Vertex, - aCircle2, - Standard_True); - addToModel(aSecondEdgeCurve); - - // Performing removal of duplicate Circles. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateCircles(); - - // Check that nothing was removed. - EXPECT_TRUE(aRemovedEntities.IsEmpty()); -} - -// Check that equal Circles are merged for StepShape_EdgeCurve. -TEST_F(MergeSTEPEntities_CircleProcessorTest, StepShape_EdgeCurve) -{ - // Creating Circles. - Handle(StepGeom_Circle) aCircle1 = addCircle(); - Handle(StepGeom_Circle) aCircle2 = addCircle(); - - // Creating EdgeCurve containing the first Circle. - Handle(StepShape_EdgeCurve) aFirstEdgeCurve = new StepShape_EdgeCurve; - aFirstEdgeCurve->Init(new TCollection_HAsciiString, - new StepShape_Vertex, - new StepShape_Vertex, - aCircle1, - Standard_True); - addToModel(aFirstEdgeCurve); - - // Creating EdgeCurve containing the second Circle. - Handle(StepShape_EdgeCurve) aSecondEdgeCurve = new StepShape_EdgeCurve; - aSecondEdgeCurve->Init(new TCollection_HAsciiString, - new StepShape_Vertex, - new StepShape_Vertex, - aCircle2, - Standard_True); - addToModel(aSecondEdgeCurve); - - // Performing removal of duplicate Circles. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateCircles(); - - // Check that one Circle was removed. - EXPECT_EQ(aRemovedEntities.Size(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(aCircle1) || aRemovedEntities.Contains(aCircle2)); -} - -// Check that equal Circles are merged for StepGeom_SurfaceCurve. -TEST_F(MergeSTEPEntities_CircleProcessorTest, StepGeom_SurfaceCurve) -{ - // Creating Circles. - Handle(StepGeom_Circle) aCircle1 = addCircle(); - Handle(StepGeom_Circle) aCircle2 = addCircle(); - - // Creating SurfaceCurve containing the first Circle. - Handle(StepGeom_SurfaceCurve) aFirstSurfaceCurve = new StepGeom_SurfaceCurve; - aFirstSurfaceCurve->Init(new TCollection_HAsciiString, - aCircle1, - new StepGeom_HArray1OfPcurveOrSurface, - StepGeom_pscrCurve3d); - addToModel(aFirstSurfaceCurve); - - // Creating SurfaceCurve containing the second Circle. - Handle(StepGeom_SurfaceCurve) aSecondSurfaceCurve = new StepGeom_SurfaceCurve; - aSecondSurfaceCurve->Init(new TCollection_HAsciiString, - aCircle2, - new StepGeom_HArray1OfPcurveOrSurface, - StepGeom_pscrCurve3d); - addToModel(aSecondSurfaceCurve); - - // Performing removal of duplicate Circles. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateCircles(); - - // Check that one Circle was removed. - EXPECT_EQ(aRemovedEntities.Size(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(aCircle1) || aRemovedEntities.Contains(aCircle2)); -} - -// Check that equal Circles are merged for StepGeom_SeamCurve. -TEST_F(MergeSTEPEntities_CircleProcessorTest, StepGeom_SeamCurve) -{ - // Creating Circles. - Handle(StepGeom_Circle) aCircle1 = addCircle(); - Handle(StepGeom_Circle) aCircle2 = addCircle(); - - // Creating SeamCurve containing the first Circle. - Handle(StepGeom_SeamCurve) aFirstSeamCurve = new StepGeom_SeamCurve; - aFirstSeamCurve->Init(new TCollection_HAsciiString, - aCircle1, - new StepGeom_HArray1OfPcurveOrSurface, - StepGeom_pscrCurve3d); - addToModel(aFirstSeamCurve); - - // Creating SeamCurve containing the second Circle. - Handle(StepGeom_SeamCurve) aSecondSeamCurve = new StepGeom_SeamCurve; - aSecondSeamCurve->Init(new TCollection_HAsciiString, - aCircle2, - new StepGeom_HArray1OfPcurveOrSurface, - StepGeom_pscrCurve3d); - addToModel(aSecondSeamCurve); - - // Performing removal of duplicate Circles. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateCircles(); - - // Check that one Circle was removed. - EXPECT_EQ(aRemovedEntities.Size(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(aCircle1) || aRemovedEntities.Contains(aCircle2)); -} diff --git a/src/DataExchange/TKDESTEP/GTests/MergeSTEPEntities_DirectionProcessor_Test.cxx b/src/DataExchange/TKDESTEP/GTests/MergeSTEPEntities_DirectionProcessor_Test.cxx deleted file mode 100644 index 876cd29230..0000000000 --- a/src/DataExchange/TKDESTEP/GTests/MergeSTEPEntities_DirectionProcessor_Test.cxx +++ /dev/null @@ -1,157 +0,0 @@ -// 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 "MergeSTEPEntities_BaseTestFixture.hxx" - -#include - -#include -#include - -class MergeSTEPEntities_DirectionProcessorTest : public MergeSTEPEntities_BaseTestFixture -{ -protected: - //! Perform removal of duplicate entities. - TColStd_MapOfTransient replaceDuplicateDirections() - { - MergeSTEPEntities_DirectionProcessor aProcessor(myWS); - for (Standard_Integer anIndex = 1; anIndex <= myWS->Model()->NbEntities(); ++anIndex) - { - aProcessor.ProcessEntity(myWS->Model()->Value(anIndex)); - } - - TColStd_MapOfTransient aRemovedEntities; - aProcessor.Perform(aRemovedEntities); - return aRemovedEntities; - } -}; - -// Check that directions with the same coordinates and different names are not merged. -TEST_F(MergeSTEPEntities_DirectionProcessorTest, DifferentNames) -{ - // Creating directions. - Handle(StepGeom_Direction) aDir1 = addDirection("dir1"); - Handle(StepGeom_Direction) aDir2 = addDirection("dir2"); - - // Creating vector containing the first direction. - Handle(StepGeom_Vector) aFirstVector = new StepGeom_Vector; - aFirstVector->Init(new TCollection_HAsciiString, aDir1, 1.); - addToModel(aFirstVector); - - // Creating vector containing the second direction. - Handle(StepGeom_Vector) aSecondVector = new StepGeom_Vector; - aSecondVector->Init(new TCollection_HAsciiString, aDir2, 1.); - addToModel(aSecondVector); - - // Performing removal of duplicate directions. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateDirections(); - - // Check that nothing was removed. - EXPECT_TRUE(aRemovedEntities.IsEmpty()); -} - -// Check that directions with the same coordinates and same names are -// merged for StepGeom_Axis1Placement. -TEST_F(MergeSTEPEntities_DirectionProcessorTest, StepGeom_Axis1Placement) -{ - // Creating directions. - Handle(StepGeom_Direction) aDir1 = addDirection(); - Handle(StepGeom_Direction) aDir2 = addDirection(); - - // Creating Cartesian point for the location. - Handle(StepGeom_CartesianPoint) aLocation = new StepGeom_CartesianPoint; - Handle(TColStd_HArray1OfReal) aLocationCoords = new TColStd_HArray1OfReal(1, 3); - aLocationCoords->SetValue(1, 0.); - aLocationCoords->SetValue(2, 0.); - aLocationCoords->SetValue(3, 0.); - aLocation->Init(new TCollection_HAsciiString, aLocationCoords); - addToModel(aLocation); - - // Creating axis containing the first direction. - Handle(StepGeom_Axis1Placement) aFirstAxis = new StepGeom_Axis1Placement; - aFirstAxis->Init(new TCollection_HAsciiString, aLocation, true, aDir1); - addToModel(aFirstAxis); - - // Creating axis containing the second direction. - Handle(StepGeom_Axis1Placement) aSecondAxis = new StepGeom_Axis1Placement; - aSecondAxis->Init(new TCollection_HAsciiString, aLocation, true, aDir2); - addToModel(aSecondAxis); - - // Performing removal of duplicate Cartesian points. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateDirections(); - - // Check that duplicate was removed. - EXPECT_EQ(aRemovedEntities.Size(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(aDir1) || aRemovedEntities.Contains(aDir2)); -} - -// Check that directions with the same coordinates and same names are -// merged for StepGeom_Axis2Placement. -TEST_F(MergeSTEPEntities_DirectionProcessorTest, StepGeom_Axis2Placement) -{ - // Creating directions. - Handle(StepGeom_Direction) aDir1 = addDirection(); - Handle(StepGeom_Direction) aDir2 = addDirection(); - - // Creating Cartesian point for the location. - Handle(StepGeom_CartesianPoint) aLocation = new StepGeom_CartesianPoint; - Handle(TColStd_HArray1OfReal) aLocationCoords = new TColStd_HArray1OfReal(1, 3); - aLocationCoords->SetValue(1, 0.); - aLocationCoords->SetValue(2, 0.); - aLocationCoords->SetValue(3, 0.); - aLocation->Init(new TCollection_HAsciiString, aLocationCoords); - addToModel(aLocation); - - // Creating axis containing the first direction. - Handle(StepGeom_Axis2Placement3d) aFirstAxis = new StepGeom_Axis2Placement3d; - aFirstAxis->Init(new TCollection_HAsciiString, aLocation, true, aDir1, false, nullptr); - addToModel(aFirstAxis); - - // Creating axis containing the second direction. - Handle(StepGeom_Axis2Placement3d) aSecondAxis = new StepGeom_Axis2Placement3d; - aSecondAxis->Init(new TCollection_HAsciiString, aLocation, true, aDir2, false, nullptr); - addToModel(aSecondAxis); - - // Performing removal of duplicate Cartesian points. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateDirections(); - - // Check that duplicate was removed. - EXPECT_EQ(aRemovedEntities.Size(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(aDir1) || aRemovedEntities.Contains(aDir2)); -} - -// Check that points with the same coordinates and same names are -// merged for StepGeom_Vector. -TEST_F(MergeSTEPEntities_DirectionProcessorTest, StepGeom_Vector) -{ - // Creating directions. - Handle(StepGeom_Direction) aDir1 = addDirection(); - Handle(StepGeom_Direction) aDir2 = addDirection(); - - // Creating vector containing the first direction. - Handle(StepGeom_Vector) aFirstVector = new StepGeom_Vector; - aFirstVector->Init(new TCollection_HAsciiString, aDir1, 1.); - addToModel(aFirstVector); - - // Creating vector containing the second direction. - Handle(StepGeom_Vector) aSecondVector = new StepGeom_Vector; - aSecondVector->Init(new TCollection_HAsciiString, aDir2, 1.); - addToModel(aSecondVector); - - // Performing removal of duplicate Cartesian points. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateDirections(); - - // Check that duplicate was removed. - EXPECT_EQ(aRemovedEntities.Size(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(aDir1) || aRemovedEntities.Contains(aDir2)); -} diff --git a/src/DataExchange/TKDESTEP/GTests/MergeSTEPEntities_LineProcessor_Test.cxx b/src/DataExchange/TKDESTEP/GTests/MergeSTEPEntities_LineProcessor_Test.cxx deleted file mode 100644 index ed3ec53ee4..0000000000 --- a/src/DataExchange/TKDESTEP/GTests/MergeSTEPEntities_LineProcessor_Test.cxx +++ /dev/null @@ -1,239 +0,0 @@ -// 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 "MergeSTEPEntities_BaseTestFixture.hxx" - -#include - -#include -#include -#include -#include -#include -#include - -class MergeSTEPEntities_LineProcessorTest : public MergeSTEPEntities_BaseTestFixture -{ -protected: - //! Perform removal of duplicate entities. - TColStd_MapOfTransient replaceDuplicateLines() - { - MergeSTEPEntities_LineProcessor aProcessor(myWS); - for (Standard_Integer anIndex = 1; anIndex <= myWS->Model()->NbEntities(); ++anIndex) - { - aProcessor.ProcessEntity(myWS->Model()->Value(anIndex)); - } - - TColStd_MapOfTransient aRemovedEntities; - aProcessor.Perform(aRemovedEntities); - return aRemovedEntities; - } -}; - -// Check that Lines with different names are not merged. -TEST_F(MergeSTEPEntities_LineProcessorTest, DifferentNames) -{ - // Creating Lines. - Handle(StepGeom_Line) aLine1 = addLine("Line1"); - Handle(StepGeom_Line) aLine2 = addLine("Line2"); - - // Creating EdgeCurve containing the first Line. - Handle(StepShape_EdgeCurve) aFirstEdgeCurve = new StepShape_EdgeCurve; - aFirstEdgeCurve->Init(new TCollection_HAsciiString, - new StepShape_Vertex, - new StepShape_Vertex, - aLine1, - Standard_True); - addToModel(aFirstEdgeCurve); - - // Creating EdgeCurve containing the second Line. - Handle(StepShape_EdgeCurve) aSecondEdgeCurve = new StepShape_EdgeCurve; - aSecondEdgeCurve->Init(new TCollection_HAsciiString, - new StepShape_Vertex, - new StepShape_Vertex, - aLine2, - Standard_True); - addToModel(aSecondEdgeCurve); - - // Performing removal of duplicate Lines. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateLines(); - - // Check that nothing was removed. - EXPECT_TRUE(aRemovedEntities.IsEmpty()); -} - -// Check that equal Lines are merged for StepShape_EdgeCurve. -TEST_F(MergeSTEPEntities_LineProcessorTest, StepShape_EdgeCurve) -{ - // Creating Lines. - Handle(StepGeom_Line) aLine1 = addLine(); - Handle(StepGeom_Line) aLine2 = addLine(); - - // Creating EdgeCurve containing the first Line. - Handle(StepShape_EdgeCurve) aFirstEdgeCurve = new StepShape_EdgeCurve; - aFirstEdgeCurve->Init(new TCollection_HAsciiString, - new StepShape_Vertex, - new StepShape_Vertex, - aLine1, - Standard_True); - addToModel(aFirstEdgeCurve); - - // Creating EdgeCurve containing the second Line. - Handle(StepShape_EdgeCurve) aSecondEdgeCurve = new StepShape_EdgeCurve; - aSecondEdgeCurve->Init(new TCollection_HAsciiString, - new StepShape_Vertex, - new StepShape_Vertex, - aLine2, - Standard_True); - addToModel(aSecondEdgeCurve); - - // Performing removal of duplicate Lines. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateLines(); - - // Check that one Line was removed. - EXPECT_EQ(aRemovedEntities.Size(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(aLine1) || aRemovedEntities.Contains(aLine2)); -} - -// Check that equal Lines are merged for StepGeom_TrimmedCurve. -TEST_F(MergeSTEPEntities_LineProcessorTest, StepGeom_TrimmedCurve) -{ - // Creating Lines. - Handle(StepGeom_Line) aLine1 = addLine(); - Handle(StepGeom_Line) aLine2 = addLine(); - - // Creating TrimmedCurve containing the first Line. - Handle(StepGeom_TrimmedCurve) aFirstTrimmedCurve = new StepGeom_TrimmedCurve; - aFirstTrimmedCurve->Init(new TCollection_HAsciiString, - aLine1, - new StepGeom_HArray1OfTrimmingSelect, - new StepGeom_HArray1OfTrimmingSelect, - Standard_True, - StepGeom_tpUnspecified); - addToModel(aFirstTrimmedCurve); - - // Creating TrimmedCurve containing the second Line. - Handle(StepGeom_TrimmedCurve) aSecondTrimmedCurve = new StepGeom_TrimmedCurve; - aSecondTrimmedCurve->Init(new TCollection_HAsciiString, - aLine2, - new StepGeom_HArray1OfTrimmingSelect, - new StepGeom_HArray1OfTrimmingSelect, - Standard_True, - StepGeom_tpUnspecified); - addToModel(aSecondTrimmedCurve); - - // Performing removal of duplicate Lines. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateLines(); - - // Check that one Line was removed. - EXPECT_EQ(aRemovedEntities.Size(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(aLine1) || aRemovedEntities.Contains(aLine2)); -} - -// Check that equal Lines are merged for StepGeom_SurfaceCurve. -TEST_F(MergeSTEPEntities_LineProcessorTest, StepGeom_SurfaceCurve) -{ - // Creating Lines. - Handle(StepGeom_Line) aLine1 = addLine(); - Handle(StepGeom_Line) aLine2 = addLine(); - - // Creating SurfaceCurve containing the first Line. - Handle(StepGeom_SurfaceCurve) aFirstSurfaceCurve = new StepGeom_SurfaceCurve; - aFirstSurfaceCurve->Init(new TCollection_HAsciiString, - aLine1, - new StepGeom_HArray1OfPcurveOrSurface, - StepGeom_pscrCurve3d); - addToModel(aFirstSurfaceCurve); - - // Creating SurfaceCurve containing the second Line. - Handle(StepGeom_SurfaceCurve) aSecondSurfaceCurve = new StepGeom_SurfaceCurve; - aSecondSurfaceCurve->Init(new TCollection_HAsciiString, - aLine2, - new StepGeom_HArray1OfPcurveOrSurface, - StepGeom_pscrCurve3d); - addToModel(aSecondSurfaceCurve); - - // Performing removal of duplicate Lines. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateLines(); - - // Check that one Line was removed. - EXPECT_EQ(aRemovedEntities.Size(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(aLine1) || aRemovedEntities.Contains(aLine2)); -} - -// Check that equal Lines are merged for StepRepr_DefinitionalRepresentation. -TEST_F(MergeSTEPEntities_LineProcessorTest, StepRepr_DefinitionalRepresentation) -{ - // Creating Lines. - Handle(StepGeom_Line) aLine1 = addLine(); - Handle(StepGeom_Line) aLine2 = addLine(); - - // Creating DefinitionalRepresentation containing the first Line. - Handle(StepRepr_HArray1OfRepresentationItem) aFirstItems = - new StepRepr_HArray1OfRepresentationItem(1, 1); - aFirstItems->SetValue(1, aLine1); - Handle(StepRepr_DefinitionalRepresentation) aFirstDefinitionalRepresentation = - new StepRepr_DefinitionalRepresentation; - aFirstDefinitionalRepresentation->Init(new TCollection_HAsciiString, - aFirstItems, - new StepRepr_RepresentationContext); - addToModel(aFirstDefinitionalRepresentation); - - // Creating DefinitionalRepresentation containing the second Line. - Handle(StepRepr_HArray1OfRepresentationItem) aSecondItems = - new StepRepr_HArray1OfRepresentationItem(1, 1); - aSecondItems->SetValue(1, aLine2); - Handle(StepRepr_DefinitionalRepresentation) aSecondDefinitionalRepresentation = - new StepRepr_DefinitionalRepresentation; - aSecondDefinitionalRepresentation->Init(new TCollection_HAsciiString, - aSecondItems, - new StepRepr_RepresentationContext); - - // Performing removal of duplicate Lines. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateLines(); - - // Check that one Line was removed. - EXPECT_EQ(aRemovedEntities.Size(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(aLine1) || aRemovedEntities.Contains(aLine2)); -} - -// Check that equal Lines are merged for StepGeom_SeamCurve. -TEST_F(MergeSTEPEntities_LineProcessorTest, StepGeom_SeamCurve) -{ - // Creating Lines. - Handle(StepGeom_Line) aLine1 = addLine(); - Handle(StepGeom_Line) aLine2 = addLine(); - - // Creating SeamCurve containing the first Line. - Handle(StepGeom_SeamCurve) aFirstSeamCurve = new StepGeom_SeamCurve; - aFirstSeamCurve->Init(new TCollection_HAsciiString, - aLine1, - new StepGeom_HArray1OfPcurveOrSurface, - StepGeom_pscrCurve3d); - addToModel(aFirstSeamCurve); - - // Creating SeamCurve containing the second Line. - Handle(StepGeom_SeamCurve) aSecondSeamCurve = new StepGeom_SeamCurve; - aSecondSeamCurve->Init(new TCollection_HAsciiString, - aLine2, - new StepGeom_HArray1OfPcurveOrSurface, - StepGeom_pscrCurve3d); - addToModel(aSecondSeamCurve); - - // Performing removal of duplicate Lines. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateLines(); - - // Check that one Line was removed. - EXPECT_EQ(aRemovedEntities.Size(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(aLine1) || aRemovedEntities.Contains(aLine2)); -} diff --git a/src/DataExchange/TKDESTEP/GTests/MergeSTEPEntities_Merger_Test.cxx b/src/DataExchange/TKDESTEP/GTests/MergeSTEPEntities_Merger_Test.cxx deleted file mode 100644 index 1ce9630db6..0000000000 --- a/src/DataExchange/TKDESTEP/GTests/MergeSTEPEntities_Merger_Test.cxx +++ /dev/null @@ -1,113 +0,0 @@ -// 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 "MergeSTEPEntities_BaseTestFixture.hxx" - -#include - -#include - -class MergeSTEPEntities_MergerTest : public MergeSTEPEntities_BaseTestFixture -{ -protected: - // Get the number of entities of the specified type. - // @param theType the type of entities to count. - // @return the number of entities of the specified type. - int getEntitiesCount(const Handle(Standard_Type)& theType) const - { - int aCount = 0; - for (Standard_Integer i = 1; i <= myWS->Model()->NbEntities(); i++) - { - if (myWS->Model()->Value(i)->IsKind(theType)) - { - aCount++; - } - } - return aCount; - } - - //! Perform removal of duplicate entities points. - void performRemoval() - { - MergeSTEPEntities_Merger aMerger(myWS); - aMerger.Perform(); - } -}; - -// Check that entities with the same coordinates and different names are not merged. -TEST_F(MergeSTEPEntities_MergerTest, DifferentEntities) -{ - // Creating directions. - Handle(StepGeom_Direction) aDir1 = addDirection("dir1"); - Handle(StepGeom_Direction) aDir2 = addDirection("dir2"); - - // Creating vector containing the first direction. - Handle(StepGeom_Vector) aFirstVector = new StepGeom_Vector; - aFirstVector->Init(new TCollection_HAsciiString, aDir1, 1.); - addToModel(aFirstVector); - - // Creating vector containing the second direction. - Handle(StepGeom_Vector) aSecondVector = new StepGeom_Vector; - aSecondVector->Init(new TCollection_HAsciiString, aDir2, 1.); - addToModel(aSecondVector); - - const int aDirectionCountBefore = getEntitiesCount(STANDARD_TYPE(StepGeom_Direction)); - - // Performing removal of duplicate directions. - performRemoval(); - - const int aDirectionCountAfter = getEntitiesCount(STANDARD_TYPE(StepGeom_Direction)); - - // Check that nothing was removed. - EXPECT_EQ(aDirectionCountBefore, 2); - EXPECT_EQ(aDirectionCountBefore, aDirectionCountAfter); -} - -// Check that entities with the same coordinates and same names are -// merged for StepGeom_Axis1Placement. -TEST_F(MergeSTEPEntities_MergerTest, EqualEntities) -{ - // Creating directions. - Handle(StepGeom_Direction) aDir1 = addDirection(); - Handle(StepGeom_Direction) aDir2 = addDirection(); - - // Creating Cartesian point for the location. - Handle(StepGeom_CartesianPoint) aLocation = new StepGeom_CartesianPoint; - Handle(TColStd_HArray1OfReal) aLocationCoords = new TColStd_HArray1OfReal(1, 3); - aLocationCoords->SetValue(1, 0.); - aLocationCoords->SetValue(2, 0.); - aLocationCoords->SetValue(3, 0.); - aLocation->Init(new TCollection_HAsciiString, aLocationCoords); - addToModel(aLocation); - - // Creating axis containing the first direction. - Handle(StepGeom_Axis1Placement) aFirstAxis = new StepGeom_Axis1Placement; - aFirstAxis->Init(new TCollection_HAsciiString, aLocation, true, aDir1); - addToModel(aFirstAxis); - - // Creating axis containing the second direction. - Handle(StepGeom_Axis1Placement) aSecondAxis = new StepGeom_Axis1Placement; - aSecondAxis->Init(new TCollection_HAsciiString, aLocation, true, aDir2); - addToModel(aSecondAxis); - - const int aDirectionCountBefore = getEntitiesCount(STANDARD_TYPE(StepGeom_Direction)); - - // Performing removal of duplicate directions. - performRemoval(); - - const int aDirectionCountAfter = getEntitiesCount(STANDARD_TYPE(StepGeom_Direction)); - - // Check that one direction was removed. - EXPECT_EQ(aDirectionCountBefore, 2); - EXPECT_EQ(aDirectionCountAfter, 1); -} diff --git a/src/DataExchange/TKDESTEP/GTests/MergeSTEPEntities_PlaneProcessor_Test.cxx b/src/DataExchange/TKDESTEP/GTests/MergeSTEPEntities_PlaneProcessor_Test.cxx deleted file mode 100644 index 64388d5494..0000000000 --- a/src/DataExchange/TKDESTEP/GTests/MergeSTEPEntities_PlaneProcessor_Test.cxx +++ /dev/null @@ -1,128 +0,0 @@ -// 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 "MergeSTEPEntities_BaseTestFixture.hxx" - -#include - -#include -#include -#include - -class MergeSTEPEntities_PlaneProcessorTest : public MergeSTEPEntities_BaseTestFixture -{ -protected: - //! Perform removal of duplicate entities. - TColStd_MapOfTransient replaceDuplicatePlanes() - { - MergeSTEPEntities_PlaneProcessor aProcessor(myWS); - for (Standard_Integer anIndex = 1; anIndex <= myWS->Model()->NbEntities(); ++anIndex) - { - aProcessor.ProcessEntity(myWS->Model()->Value(anIndex)); - } - - TColStd_MapOfTransient aRemovedEntities; - aProcessor.Perform(aRemovedEntities); - return aRemovedEntities; - } -}; - -// Check that Planes with different names are not merged. -TEST_F(MergeSTEPEntities_PlaneProcessorTest, DifferentNames) -{ - // Creating Planes. - Handle(StepGeom_Plane) aPlane1 = addPlane("Plane1"); - Handle(StepGeom_Plane) aPlane2 = addPlane("Plane2"); - - // Creating StepShape_AdvancedFace containing the first Plane. - Handle(StepShape_AdvancedFace) aFirstAdvancedFace = new StepShape_AdvancedFace; - aFirstAdvancedFace->Init(new TCollection_HAsciiString, - new StepShape_HArray1OfFaceBound, - aPlane1, - Standard_True); - addToModel(aFirstAdvancedFace); - - // Creating StepShape_AdvancedFace containing the second Plane. - Handle(StepShape_AdvancedFace) aSecondAdvancedFace = new StepShape_AdvancedFace; - aSecondAdvancedFace->Init(new TCollection_HAsciiString, - new StepShape_HArray1OfFaceBound, - aPlane2, - Standard_True); - addToModel(aSecondAdvancedFace); - - // Performing removal of duplicate Planes. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicatePlanes(); - - // Check that nothing was removed. - EXPECT_TRUE(aRemovedEntities.IsEmpty()); -} - -// Check that equal Planes are merged for StepShape_AdvancedFace. -TEST_F(MergeSTEPEntities_PlaneProcessorTest, StepShape_AdvancedFace) -{ - // Creating Planes. - Handle(StepGeom_Plane) aPlane1 = addPlane(); - Handle(StepGeom_Plane) aPlane2 = addPlane(); - - // Creating StepShape_AdvancedFace containing the first Plane. - Handle(StepShape_AdvancedFace) aFirstAdvancedFace = new StepShape_AdvancedFace; - aFirstAdvancedFace->Init(new TCollection_HAsciiString, - new StepShape_HArray1OfFaceBound, - aPlane1, - Standard_True); - addToModel(aFirstAdvancedFace); - - // Creating StepShape_AdvancedFace containing the second Plane. - Handle(StepShape_AdvancedFace) aSecondAdvancedFace = new StepShape_AdvancedFace; - aSecondAdvancedFace->Init(new TCollection_HAsciiString, - new StepShape_HArray1OfFaceBound, - aPlane2, - Standard_True); - addToModel(aSecondAdvancedFace); - - // Performing removal of duplicate Planes. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicatePlanes(); - - // Check that one Plane was removed. - EXPECT_EQ(aRemovedEntities.Size(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(aPlane1) || aRemovedEntities.Contains(aPlane2)); -} - -// Check that equal Planes are merged for StepGeom_Pcurve. -TEST_F(MergeSTEPEntities_PlaneProcessorTest, StepGeom_Pcurve) -{ - // Creating Planes. - Handle(StepGeom_Plane) aPlane1 = addPlane(); - Handle(StepGeom_Plane) aPlane2 = addPlane(); - - // Creating StepGeom_Pcurve containing the first Plane. - Handle(StepGeom_Pcurve) aFirstPcurve = new StepGeom_Pcurve; - aFirstPcurve->Init(new TCollection_HAsciiString, - aPlane1, - new StepRepr_DefinitionalRepresentation); - addToModel(aFirstPcurve); - - // Creating StepGeom_Pcurve containing the second Plane. - Handle(StepGeom_Pcurve) aSecondPcurve = new StepGeom_Pcurve; - aSecondPcurve->Init(new TCollection_HAsciiString, - aPlane2, - new StepRepr_DefinitionalRepresentation); - addToModel(aSecondPcurve); - - // Performing removal of duplicate Planes. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicatePlanes(); - - // Check that one Plane was removed. - EXPECT_EQ(aRemovedEntities.Size(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(aPlane1) || aRemovedEntities.Contains(aPlane2)); -} diff --git a/src/DataExchange/TKDESTEP/GTests/MergeSTEPEntities_VectorProcessor_Test.cxx b/src/DataExchange/TKDESTEP/GTests/MergeSTEPEntities_VectorProcessor_Test.cxx deleted file mode 100644 index c66edf06eb..0000000000 --- a/src/DataExchange/TKDESTEP/GTests/MergeSTEPEntities_VectorProcessor_Test.cxx +++ /dev/null @@ -1,92 +0,0 @@ -// 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 "MergeSTEPEntities_BaseTestFixture.hxx" - -#include - -#include - -class MergeSTEPEntities_VectorProcessorTest : public MergeSTEPEntities_BaseTestFixture -{ -protected: - //! Perform removal of duplicate entities. - TColStd_MapOfTransient replaceDuplicateVectors() - { - MergeSTEPEntities_VectorProcessor aProcessor(myWS); - for (Standard_Integer anIndex = 1; anIndex <= myWS->Model()->NbEntities(); ++anIndex) - { - aProcessor.ProcessEntity(myWS->Model()->Value(anIndex)); - } - - TColStd_MapOfTransient aRemovedEntities; - aProcessor.Perform(aRemovedEntities); - return aRemovedEntities; - } -}; - -// Check that Vectors with the same coordinates and different names are not merged. -TEST_F(MergeSTEPEntities_VectorProcessorTest, DifferentNames) -{ - // Creating Vectors. - Handle(StepGeom_Vector) aVec1 = addVector("vec1"); - Handle(StepGeom_Vector) aVec2 = addVector("vec2"); - - // Creating a cartesian point for the lines. - Handle(StepGeom_CartesianPoint) aPnt = addCartesianPoint(nullptr, {0., 0., 0.}); - - // Creating aLine containing the first Vector. - Handle(StepGeom_Line) aLine1 = new StepGeom_Line; - aLine1->Init(new TCollection_HAsciiString, aPnt, aVec1); - addToModel(aLine1); - - // Creating aLine containing the second Vector. - Handle(StepGeom_Line) aLine2 = new StepGeom_Line; - aLine2->Init(new TCollection_HAsciiString, aPnt, aVec2); - addToModel(aLine2); - - // Performing removal of duplicate Vectors. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateVectors(); - - // Check that nothing was removed. - EXPECT_TRUE(aRemovedEntities.IsEmpty()); -} - -// Check that Vectors with the same coordinates and same names are -// merged for StepGeom_Axis1Placement. -TEST_F(MergeSTEPEntities_VectorProcessorTest, StepGeom_Line) -{ - // Creating Vectors. - Handle(StepGeom_Vector) aVec1 = addVector(); - Handle(StepGeom_Vector) aVec2 = addVector(); - - // Creating a cartesian point for the lines. - Handle(StepGeom_CartesianPoint) aPnt = addCartesianPoint(nullptr, {0., 0., 0.}); - - // Creating aLine containing the first Vector. - Handle(StepGeom_Line) aLine1 = new StepGeom_Line; - aLine1->Init(new TCollection_HAsciiString, aPnt, aVec1); - addToModel(aLine1); - - // Creating aLine containing the second Vector. - Handle(StepGeom_Line) aLine2 = new StepGeom_Line; - aLine2->Init(new TCollection_HAsciiString, aPnt, aVec2); - addToModel(aLine2); - - // Performing removal of duplicate Vectors. - TColStd_MapOfTransient aRemovedEntities = replaceDuplicateVectors(); - - // Check that duplicate was removed. - EXPECT_EQ(aRemovedEntities.Size(), 1); - EXPECT_TRUE(aRemovedEntities.Contains(aVec1) || aRemovedEntities.Contains(aVec2)); -} diff --git a/src/DataExchange/TKDESTEP/GTests/StepTidy_Axis2Placement3dReducer_Test.cxx b/src/DataExchange/TKDESTEP/GTests/StepTidy_Axis2Placement3dReducer_Test.cxx new file mode 100644 index 0000000000..956e17f006 --- /dev/null +++ b/src/DataExchange/TKDESTEP/GTests/StepTidy_Axis2Placement3dReducer_Test.cxx @@ -0,0 +1,461 @@ +// 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 "StepTidy_BaseTestFixture.pxx" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class StepTidy_Axis2Placement3dReducerTest : public StepTidy_BaseTestFixture +{ +protected: + //! Perform removal of duplicate entities. + TColStd_MapOfTransient replaceDuplicateAxis2Placement3ds() + { + StepTidy_Axis2Placement3dReducer aReducer(myWS); + for (Standard_Integer anIndex = 1; anIndex <= myWS->Model()->NbEntities(); ++anIndex) + { + aReducer.ProcessEntity(myWS->Model()->Value(anIndex)); + } + + TColStd_MapOfTransient aRemovedEntities; + aReducer.Perform(aRemovedEntities); + return aRemovedEntities; + } +}; + +// Check that Axis2Placement3ds with the same coordinates and different names are not merged. +TEST_F(StepTidy_Axis2Placement3dReducerTest, DifferentNames) +{ + // Creating Axis2Placement3ds. + Handle(StepGeom_Axis2Placement3d) anAxis1 = addAxis2Placement3d("Axis1"); + Handle(StepGeom_Axis2Placement3d) anAxis2 = addAxis2Placement3d("Axis2"); + + // Creating a plane containing the first Axis2Placement3d. + Handle(StepGeom_Plane) aPlane1 = new StepGeom_Plane; + aPlane1->Init(new TCollection_HAsciiString, anAxis1); + addToModel(aPlane1); + + // Creating a plane containing the second Axis2Placement3d. + Handle(StepGeom_Plane) aPlane2 = new StepGeom_Plane; + aPlane2->Init(new TCollection_HAsciiString, anAxis2); + addToModel(aPlane2); + + // Performing removal of duplicate Axis2Placement3ds. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateAxis2Placement3ds(); + + // Check that nothing was removed. + EXPECT_TRUE(aRemovedEntities.IsEmpty()); +} + +// Check that equal Axis2Placement3ds are merged for StepShape_GeometricCurveSet. +TEST_F(StepTidy_Axis2Placement3dReducerTest, StepGeom_Plane) +{ + // Creating Axis2Placement3ds. + Handle(StepGeom_Axis2Placement3d) anAxis1 = addAxis2Placement3d(); + Handle(StepGeom_Axis2Placement3d) anAxis2 = addAxis2Placement3d(); + + // Creating a plane containing the first Axis2Placement3d. + Handle(StepGeom_Plane) aPlane1 = new StepGeom_Plane; + aPlane1->Init(new TCollection_HAsciiString, anAxis1); + addToModel(aPlane1); + + // Creating a plane containing the second Axis2Placement3d. + Handle(StepGeom_Plane) aPlane2 = new StepGeom_Plane; + aPlane2->Init(new TCollection_HAsciiString, anAxis2); + addToModel(aPlane2); + + // Performing removal of duplicate Axis2Placement3ds. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateAxis2Placement3ds(); + + // Check that one Axis2Placement3d was removed. + EXPECT_EQ(aRemovedEntities.Extent(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(anAxis1) || aRemovedEntities.Contains(anAxis2)); +} + +// Check that equal Axis2Placement3ds are merged for StepRepr_ItemDefinedTransformation. +TEST_F(StepTidy_Axis2Placement3dReducerTest, StepRepr_ItemDefinedTransformation) +{ + // Creating Axis2Placement3ds. + Handle(StepGeom_Axis2Placement3d) anAxis1 = addAxis2Placement3d(); + Handle(StepGeom_Axis2Placement3d) anAxis2 = addAxis2Placement3d(); + Handle(StepGeom_Axis2Placement3d) anAxis3 = addAxis2Placement3d(nullptr, gp_XYZ(1., 1., 1.)); + + // Creating ItemDefinedTransformation containing the first Axis2Placement3d. + Handle(StepRepr_ItemDefinedTransformation) aItem1 = new StepRepr_ItemDefinedTransformation; + aItem1->Init(new TCollection_HAsciiString, new TCollection_HAsciiString, anAxis1, anAxis3); + addToModel(aItem1); + + // Creating ItemDefinedTransformation containing the second Axis2Placement3d. + Handle(StepRepr_ItemDefinedTransformation) aItem2 = new StepRepr_ItemDefinedTransformation; + aItem1->Init(new TCollection_HAsciiString, new TCollection_HAsciiString, anAxis2, anAxis3); + addToModel(aItem2); + + // Performing removal of duplicate Axis2Placement3ds. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateAxis2Placement3ds(); + + // Check that one Axis2Placement3d was removed. + EXPECT_EQ(aRemovedEntities.Extent(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(anAxis1) || aRemovedEntities.Contains(anAxis2)); +} + +// Check that equal Axis2Placement3ds are merged for StepGeom_CylindricalSurface. +TEST_F(StepTidy_Axis2Placement3dReducerTest, StepGeom_CylindricalSurface) +{ + // Creating Axis2Placement3ds. + Handle(StepGeom_Axis2Placement3d) anAxis1 = addAxis2Placement3d(); + Handle(StepGeom_Axis2Placement3d) anAxis2 = addAxis2Placement3d(); + + // Creating a cylindrical surface containing the first Axis2Placement3d. + Handle(StepGeom_CylindricalSurface) aCylindricalSurface1 = new StepGeom_CylindricalSurface; + aCylindricalSurface1->Init(new TCollection_HAsciiString, anAxis1, 1.0); + addToModel(aCylindricalSurface1); + + // Creating a cylindrical surface containing the second Axis2Placement3d. + Handle(StepGeom_CylindricalSurface) aCylindricalSurface2 = new StepGeom_CylindricalSurface; + aCylindricalSurface2->Init(new TCollection_HAsciiString, anAxis2, 1.0); + addToModel(aCylindricalSurface2); + + // Performing removal of duplicate Axis2Placement3ds. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateAxis2Placement3ds(); + + // Check that one Axis2Placement3d was removed. + EXPECT_EQ(aRemovedEntities.Extent(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(anAxis1) || aRemovedEntities.Contains(anAxis2)); +} + +// Check that equal Axis2Placement3ds are merged for StepShape_ShapeRepresentation. +TEST_F(StepTidy_Axis2Placement3dReducerTest, StepShape_ShapeRepresentation) +{ + // Creating Axis2Placement3ds. + Handle(StepGeom_Axis2Placement3d) anAxis1 = addAxis2Placement3d(); + Handle(StepGeom_Axis2Placement3d) anAxis2 = addAxis2Placement3d(); + + // Creating a shape representation containing the first Axis2Placement3d. + Handle(StepRepr_HArray1OfRepresentationItem) aItems1 = + new StepRepr_HArray1OfRepresentationItem(1, 1); + aItems1->SetValue(1, anAxis1); + Handle(StepShape_ShapeRepresentation) aShapeRepresentation1 = new StepShape_ShapeRepresentation; + aShapeRepresentation1->Init(new TCollection_HAsciiString, + aItems1, + new StepRepr_RepresentationContext); + addToModel(aShapeRepresentation1); + + // Creating a shape representation containing the second Axis2Placement3d. + Handle(StepRepr_HArray1OfRepresentationItem) aItems2 = + new StepRepr_HArray1OfRepresentationItem(1, 1); + aItems2->SetValue(1, anAxis2); + Handle(StepShape_ShapeRepresentation) aShapeRepresentation2 = new StepShape_ShapeRepresentation; + aShapeRepresentation2->Init(new TCollection_HAsciiString, + aItems2, + new StepRepr_RepresentationContext); + addToModel(aShapeRepresentation2); + + // Performing removal of duplicate Axis2Placement3ds. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateAxis2Placement3ds(); + + // Check that one Axis2Placement3d was removed. + EXPECT_EQ(aRemovedEntities.Extent(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(anAxis1) || aRemovedEntities.Contains(anAxis2)); +} + +// Check that equal Axis2Placement3ds are merged for StepRepr_ConstructiveGeometryRepresentation. +TEST_F(StepTidy_Axis2Placement3dReducerTest, StepRepr_ConstructiveGeometryRepresentation) +{ + // Creating Axis2Placement3ds. + Handle(StepGeom_Axis2Placement3d) anAxis1 = addAxis2Placement3d(); + Handle(StepGeom_Axis2Placement3d) anAxis2 = addAxis2Placement3d(); + + // Creating a constructive geometry representation containing the first Axis2Placement3d. + Handle(StepRepr_HArray1OfRepresentationItem) aItems1 = + new StepRepr_HArray1OfRepresentationItem(1, 1); + aItems1->SetValue(1, anAxis1); + Handle(StepRepr_ConstructiveGeometryRepresentation) aConstructiveGeometryRepresentation1 = + new StepRepr_ConstructiveGeometryRepresentation; + aConstructiveGeometryRepresentation1->Init(new TCollection_HAsciiString, + aItems1, + new StepRepr_RepresentationContext); + addToModel(aConstructiveGeometryRepresentation1); + + // Creating a constructive geometry representation containing the second Axis2Placement3d. + Handle(StepRepr_HArray1OfRepresentationItem) aItems2 = + new StepRepr_HArray1OfRepresentationItem(1, 1); + aItems2->SetValue(1, anAxis2); + Handle(StepRepr_ConstructiveGeometryRepresentation) aConstructiveGeometryRepresentation2 = + new StepRepr_ConstructiveGeometryRepresentation; + aConstructiveGeometryRepresentation2->Init(new TCollection_HAsciiString, + aItems2, + new StepRepr_RepresentationContext); + addToModel(aConstructiveGeometryRepresentation2); + + // Performing removal of duplicate Axis2Placement3ds. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateAxis2Placement3ds(); + + // Check that one Axis2Placement3d was removed. + EXPECT_EQ(aRemovedEntities.Extent(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(anAxis1) || aRemovedEntities.Contains(anAxis2)); +} + +// Check that equal Axis2Placement3ds are merged for StepGeom_Circle. +TEST_F(StepTidy_Axis2Placement3dReducerTest, StepGeom_Circle) +{ + // Creating Axis2Placement3ds. + Handle(StepGeom_Axis2Placement3d) anAxis1 = addAxis2Placement3d(); + Handle(StepGeom_Axis2Placement3d) anAxis2 = addAxis2Placement3d(); + + // Creating a circle containing the first Axis2Placement3d. + StepGeom_Axis2Placement aSelector1; + aSelector1.SetValue(anAxis1); + Handle(StepGeom_Circle) aCircle1 = new StepGeom_Circle; + aCircle1->Init(new TCollection_HAsciiString, aSelector1, 1.0); + addToModel(aCircle1); + + // Creating a circle containing the second Axis2Placement3d. + StepGeom_Axis2Placement aSelector2; + aSelector2.SetValue(anAxis2); + Handle(StepGeom_Circle) aCircle2 = new StepGeom_Circle; + aCircle2->Init(new TCollection_HAsciiString, aSelector2, 1.0); + addToModel(aCircle2); + + // Performing removal of duplicate Axis2Placement3ds. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateAxis2Placement3ds(); + + // Check that one Axis2Placement3d was removed. + EXPECT_EQ(aRemovedEntities.Extent(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(anAxis1) || aRemovedEntities.Contains(anAxis2)); +} + +// Check that equal Axis2Placement3ds are merged for StepVisual_PresentationLayerAssignment. +TEST_F(StepTidy_Axis2Placement3dReducerTest, StepVisual_PresentationLayerAssignment) +{ + // Creating Axis2Placement3ds. + Handle(StepGeom_Axis2Placement3d) anAxis1 = addAxis2Placement3d(); + Handle(StepGeom_Axis2Placement3d) anAxis2 = addAxis2Placement3d(); + + // Creating a presentation layer assignment containing the first Axis2Placement3d. + Handle(StepVisual_HArray1OfLayeredItem) aAssignedItems1 = + new StepVisual_HArray1OfLayeredItem(1, 1); + StepVisual_LayeredItem aLayeredItem1; + aLayeredItem1.SetValue(anAxis1); + aAssignedItems1->SetValue(1, aLayeredItem1); + Handle(StepVisual_PresentationLayerAssignment) aPresentationLayerAssignment1 = + new StepVisual_PresentationLayerAssignment; + aPresentationLayerAssignment1->Init(new TCollection_HAsciiString, + new TCollection_HAsciiString, + aAssignedItems1); + addToModel(aPresentationLayerAssignment1); + + // Creating a presentation layer assignment containing the second Axis2Placement3d. + Handle(StepVisual_HArray1OfLayeredItem) aAssignedItems2 = + new StepVisual_HArray1OfLayeredItem(1, 1); + StepVisual_LayeredItem aLayeredItem2; + aLayeredItem2.SetValue(anAxis2); + aAssignedItems2->SetValue(1, aLayeredItem2); + Handle(StepVisual_PresentationLayerAssignment) aPresentationLayerAssignment2 = + new StepVisual_PresentationLayerAssignment; + aPresentationLayerAssignment2->Init(new TCollection_HAsciiString, + new TCollection_HAsciiString, + aAssignedItems2); + addToModel(aPresentationLayerAssignment2); + + // Performing removal of duplicate Axis2Placement3ds. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateAxis2Placement3ds(); + + // Check that one Axis2Placement3d was removed. + EXPECT_EQ(aRemovedEntities.Extent(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(anAxis1) || aRemovedEntities.Contains(anAxis2)); +} + +// Check that equal Axis2Placement3ds are merged for StepVisual_StyledItem. +TEST_F(StepTidy_Axis2Placement3dReducerTest, StepVisual_StyledItem) +{ + // Creating Axis2Placement3ds. + Handle(StepGeom_Axis2Placement3d) anAxis1 = addAxis2Placement3d(); + Handle(StepGeom_Axis2Placement3d) anAxis2 = addAxis2Placement3d(); + + // Creating a styled item containing the first Axis2Placement3d. + Handle(StepVisual_StyledItem) aStiledItem1 = new StepVisual_StyledItem; + aStiledItem1->Init(new TCollection_HAsciiString, + new StepVisual_HArray1OfPresentationStyleAssignment(1, 1), + anAxis1); + addToModel(aStiledItem1); + + // Creating a styled item containing the second Axis2Placement3d. + Handle(StepVisual_StyledItem) aStiledItem2 = new StepVisual_StyledItem; + aStiledItem2->Init(new TCollection_HAsciiString, + new StepVisual_HArray1OfPresentationStyleAssignment(1, 1), + anAxis2); + addToModel(aStiledItem2); + + // Performing removal of duplicate Axis2Placement3ds. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateAxis2Placement3ds(); + + // Check that one Axis2Placement3d was removed. + EXPECT_EQ(aRemovedEntities.Extent(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(anAxis1) || aRemovedEntities.Contains(anAxis2)); +} + +// Check that equal Axis2Placement3ds are merged for StepGeom_Ellipse. +TEST_F(StepTidy_Axis2Placement3dReducerTest, StepGeom_Ellipse) +{ + // Creating Axis2Placement3ds. + Handle(StepGeom_Axis2Placement3d) anAxis1 = addAxis2Placement3d(); + Handle(StepGeom_Axis2Placement3d) anAxis2 = addAxis2Placement3d(); + + // Creating an ellipse containing the first Axis2Placement3d. + StepGeom_Axis2Placement aSelector1; + aSelector1.SetValue(anAxis1); + Handle(StepGeom_Ellipse) aEllipse1 = new StepGeom_Ellipse; + aEllipse1->Init(new TCollection_HAsciiString, aSelector1, 1.0, 2.0); + addToModel(aEllipse1); + + // Creating an ellipse containing the second Axis2Placement3d. + StepGeom_Axis2Placement aSelector2; + aSelector2.SetValue(anAxis2); + Handle(StepGeom_Ellipse) aEllipse2 = new StepGeom_Ellipse; + aEllipse2->Init(new TCollection_HAsciiString, aSelector2, 1.0, 2.0); + addToModel(aEllipse2); + + // Performing removal of duplicate Axis2Placement3ds. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateAxis2Placement3ds(); + + // Check that one Axis2Placement3d was removed. + EXPECT_EQ(aRemovedEntities.Extent(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(anAxis1) || aRemovedEntities.Contains(anAxis2)); +} + +// Check that equal Axis2Placement3ds are merged for StepGeom_ConicalSurface. +TEST_F(StepTidy_Axis2Placement3dReducerTest, StepGeom_ConicalSurface) +{ + // Creating Axis2Placement3ds. + Handle(StepGeom_Axis2Placement3d) anAxis1 = addAxis2Placement3d(); + Handle(StepGeom_Axis2Placement3d) anAxis2 = addAxis2Placement3d(); + + // Creating a conical surface containing the first Axis2Placement3d. + Handle(StepGeom_ConicalSurface) aConicalSurface1 = new StepGeom_ConicalSurface; + aConicalSurface1->Init(new TCollection_HAsciiString, anAxis1, 1.0, 1.0); + addToModel(aConicalSurface1); + + // Creating a conical surface containing the second Axis2Placement3d. + Handle(StepGeom_ConicalSurface) aConicalSurface2 = new StepGeom_ConicalSurface; + aConicalSurface2->Init(new TCollection_HAsciiString, anAxis2, 1.0, 1.0); + addToModel(aConicalSurface2); + + // Performing removal of duplicate Axis2Placement3ds. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateAxis2Placement3ds(); + + // Check that one Axis2Placement3d was removed. + EXPECT_EQ(aRemovedEntities.Extent(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(anAxis1) || aRemovedEntities.Contains(anAxis2)); +} + +// Check that equal Axis2Placement3ds are merged for StepGeom_ToroidalSurface. +TEST_F(StepTidy_Axis2Placement3dReducerTest, StepGeom_ToroidalSurface) +{ + // Creating Axis2Placement3ds. + Handle(StepGeom_Axis2Placement3d) anAxis1 = addAxis2Placement3d(); + Handle(StepGeom_Axis2Placement3d) anAxis2 = addAxis2Placement3d(); + + // Creating a toroidal surface containing the first Axis2Placement3d. + Handle(StepGeom_ToroidalSurface) aToroidalSurface1 = new StepGeom_ToroidalSurface; + aToroidalSurface1->Init(new TCollection_HAsciiString, anAxis1, 1.0, 1.0); + addToModel(aToroidalSurface1); + + // Creating a toroidal surface containing the second Axis2Placement3d. + Handle(StepGeom_ToroidalSurface) aToroidalSurface2 = new StepGeom_ToroidalSurface; + aToroidalSurface2->Init(new TCollection_HAsciiString, anAxis2, 1.0, 1.0); + addToModel(aToroidalSurface2); + + // Performing removal of duplicate Axis2Placement3ds. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateAxis2Placement3ds(); + + // Check that one Axis2Placement3d was removed. + EXPECT_EQ(aRemovedEntities.Extent(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(anAxis1) || aRemovedEntities.Contains(anAxis2)); +} + +// Check that equal Axis2Placement3ds are merged for StepShape_AdvancedBrepShapeRepresentation. +TEST_F(StepTidy_Axis2Placement3dReducerTest, StepShape_AdvancedBrepShapeRepresentation) +{ + // Creating Axis2Placement3ds. + Handle(StepGeom_Axis2Placement3d) anAxis1 = addAxis2Placement3d(); + Handle(StepGeom_Axis2Placement3d) anAxis2 = addAxis2Placement3d(); + + // Creating a shape representation containing the first Axis2Placement3d. + Handle(StepRepr_HArray1OfRepresentationItem) aItems1 = + new StepRepr_HArray1OfRepresentationItem(1, 1); + aItems1->SetValue(1, anAxis1); + Handle(StepShape_AdvancedBrepShapeRepresentation) aShapeRepresentation1 = + new StepShape_AdvancedBrepShapeRepresentation; + aShapeRepresentation1->Init(new TCollection_HAsciiString, + aItems1, + new StepRepr_RepresentationContext); + addToModel(aShapeRepresentation1); + + // Creating a shape representation containing the second Axis2Placement3d. + Handle(StepRepr_HArray1OfRepresentationItem) aItems2 = + new StepRepr_HArray1OfRepresentationItem(1, 1); + aItems2->SetValue(1, anAxis2); + Handle(StepShape_AdvancedBrepShapeRepresentation) aShapeRepresentation2 = + new StepShape_AdvancedBrepShapeRepresentation; + aShapeRepresentation2->Init(new TCollection_HAsciiString, + aItems2, + new StepRepr_RepresentationContext); + addToModel(aShapeRepresentation2); + + // Performing removal of duplicate Axis2Placement3ds. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateAxis2Placement3ds(); + + // Check that one Axis2Placement3d was removed. + EXPECT_EQ(aRemovedEntities.Extent(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(anAxis1) || aRemovedEntities.Contains(anAxis2)); +} + +// Check that equal Axis2Placement3ds are merged for StepGeom_SphericalSurface. +TEST_F(StepTidy_Axis2Placement3dReducerTest, StepGeom_SphericalSurface) +{ + // Creating Axis2Placement3ds. + Handle(StepGeom_Axis2Placement3d) anAxis1 = addAxis2Placement3d(); + Handle(StepGeom_Axis2Placement3d) anAxis2 = addAxis2Placement3d(); + + // Creating a spherical surface containing the first Axis2Placement3d. + Handle(StepGeom_SphericalSurface) aSphericalSurface1 = new StepGeom_SphericalSurface; + aSphericalSurface1->Init(new TCollection_HAsciiString, anAxis1, 1.0); + addToModel(aSphericalSurface1); + + // Creating a spherical surface containing the second Axis2Placement3d. + Handle(StepGeom_SphericalSurface) aSphericalSurface2 = new StepGeom_SphericalSurface; + aSphericalSurface2->Init(new TCollection_HAsciiString, anAxis2, 1.0); + addToModel(aSphericalSurface2); + + // Performing removal of duplicate Axis2Placement3ds. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateAxis2Placement3ds(); + + // Check that one Axis2Placement3d was removed. + EXPECT_EQ(aRemovedEntities.Extent(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(anAxis1) || aRemovedEntities.Contains(anAxis2)); +} diff --git a/src/DataExchange/TKDESTEP/GTests/StepTidy_BaseTestFixture.pxx b/src/DataExchange/TKDESTEP/GTests/StepTidy_BaseTestFixture.pxx new file mode 100644 index 0000000000..23df1c6937 --- /dev/null +++ b/src/DataExchange/TKDESTEP/GTests/StepTidy_BaseTestFixture.pxx @@ -0,0 +1,194 @@ +// 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. + +#ifndef _StepTidy_BaseTestFixture_HeaderFile +#define _StepTidy_BaseTestFixture_HeaderFile + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +class StepTidy_BaseTestFixture : public testing::Test +{ +protected: + // Initialize the work session and model. + StepTidy_BaseTestFixture() + : myWS() + { + STEPControl_Controller::Init(); + myWS = new XSControl_WorkSession; + myWS->SelectNorm("STEP"); + myWS->SetModel(myWS->NormAdaptor()->NewModel()); + } + + // Add a Cartesian point to the model. + // @param theName the name of the Cartesian point. + // @param thePoint the coordinates of the Cartesian point. + // @return the added Cartesian point. + Handle(StepGeom_CartesianPoint) addCartesianPoint(const char* theName = nullptr, + const gp_XYZ& thePoint = gp_XYZ(0., + 0., + 0.)) const + { + const Handle(StepGeom_CartesianPoint) aCartesianPoint = new StepGeom_CartesianPoint; + const Handle(TCollection_HAsciiString) aName = + theName ? new TCollection_HAsciiString(theName) : new TCollection_HAsciiString(); + aCartesianPoint->Init3D(aName, thePoint.X(), thePoint.Y(), thePoint.Z()); + myWS->Model()->AddWithRefs(aCartesianPoint); + return aCartesianPoint; + } + + // Add a direction to the model. + // @param theName the name of the direction. + // @param theDirection the direction ratios. + // @return the added direction. + Handle(StepGeom_Direction) addDirection(const char* theName = nullptr, + const gp_XYZ& theDirection = gp_XYZ(0., 0., 1.)) const + { + const Handle(StepGeom_Direction) aDirection = new StepGeom_Direction; + const Handle(TCollection_HAsciiString) aName = + theName ? new TCollection_HAsciiString(theName) : new TCollection_HAsciiString(); + Handle(TColStd_HArray1OfReal) aDirectionRatios = new TColStd_HArray1OfReal(1, 3); + aDirectionRatios->SetValue(1, theDirection.X()); + aDirectionRatios->SetValue(2, theDirection.Y()); + aDirectionRatios->SetValue(3, theDirection.Z()); + aDirection->Init(aName, aDirectionRatios); + myWS->Model()->AddWithRefs(aDirection); + return aDirection; + } + + // Add a vector to the model. + // @param theName the name of the vector. + // @param theOrientation the orientation of the vector. + // @param aMagnitude the magnitude of the vector. + // @return the added vector. + Handle(StepGeom_Vector) addVector(const char* theName = nullptr, + const gp_XYZ& theOrientation = gp_XYZ(0., 0., 1.), + const double aMagnitude = 1.) const + { + const Handle(StepGeom_Vector) aVector = new StepGeom_Vector; + const Handle(TCollection_HAsciiString) aName = + theName ? new TCollection_HAsciiString(theName) : new TCollection_HAsciiString(); + aVector->Init(aName, addDirection(nullptr, theOrientation), aMagnitude); + myWS->Model()->AddWithRefs(aVector); + return aVector; + } + + // Add an Axis2Placement3d to the model. + // @param theName the name of the Axis2Placement3d. + // @param theLocation the location of the Axis2Placement3d. + // @param theAxis the axis of the Axis2Placement3d. + // @param theRefDirection the reference direction of the Axis2Placement3d. + // @return the added Axis2Placement3d. + Handle(StepGeom_Axis2Placement3d) addAxis2Placement3d( + const char* theName = nullptr, + const gp_XYZ& theLocation = gp_XYZ(0., 0., 0.), + const gp_XYZ& theAxis = gp_XYZ(0., 0., 1.), + const gp_XYZ& theRefDirection = gp_XYZ(0., 1., 0.)) const + { + const Handle(StepGeom_Axis2Placement3d) aAxis2Placement3d = new StepGeom_Axis2Placement3d; + const Handle(TCollection_HAsciiString) aName = + theName ? new TCollection_HAsciiString(theName) : new TCollection_HAsciiString(); + aAxis2Placement3d->Init(aName, + addCartesianPoint(nullptr, theLocation), + true, + addDirection(nullptr, theAxis), + true, + addDirection(nullptr, theRefDirection)); + myWS->Model()->AddWithRefs(aAxis2Placement3d); + return aAxis2Placement3d; + } + + // Add a line to the model. + // @param theName the name of the line. + // @param theLocation the location of the line. + // @param theOrientation the orientation of the line vector. + // @param theMagnitude the magnitude of the line vector. + // @return the added line. + Handle(StepGeom_Line) addLine(const char* theName = nullptr, + const gp_XYZ& theLocation = gp_XYZ(0., 0., 0.), + const gp_XYZ& theOrientation = gp_XYZ(0., 0., 1.), + const double aMagnitude = 1.) const + { + const Handle(StepGeom_Line) aLine = new StepGeom_Line; + const Handle(TCollection_HAsciiString) aName = + theName ? new TCollection_HAsciiString(theName) : new TCollection_HAsciiString(); + aLine->Init(aName, + addCartesianPoint(nullptr, theLocation), + addVector(nullptr, theOrientation, aMagnitude)); + myWS->Model()->AddWithRefs(aLine); + return aLine; + } + + // Add a circle to the model. + // @param theName the name of the circle. + // @param theLocation the location of the circle. + // @param theAxis the axis of the circle. + // @param theRefDirection the reference direction of the circle. + // @param theRadius the radius of the circle. + // @return the added circle. + Handle(StepGeom_Circle) addCircle(const char* theName = nullptr, + const gp_XYZ& theLocation = gp_XYZ(0., 0., 0.), + const gp_XYZ& theAxis = gp_XYZ(0., 0., 1.), + const gp_XYZ& theRefDirection = gp_XYZ(0., 1., 0.), + const double theRadius = 1.) const + { + const Handle(StepGeom_Circle) aCircle = new StepGeom_Circle; + const Handle(TCollection_HAsciiString) aName = + theName ? new TCollection_HAsciiString(theName) : new TCollection_HAsciiString(); + StepGeom_Axis2Placement aSelector; + aSelector.SetValue(addAxis2Placement3d(nullptr, theLocation, theAxis, theRefDirection)); + aCircle->Init(aName, aSelector, theRadius); + myWS->Model()->AddWithRefs(aCircle); + return aCircle; + } + + // Add a plane to the model. + // @param theName the name of the plane. + // @param theLocation the location of the plane. + // @param theAxis the axis of the plane. + // @param theRefDirection the reference direction of the plane. + // @return the added plane. + Handle(StepGeom_Plane) addPlane(const char* theName = nullptr, + const gp_XYZ& theLocation = gp_XYZ(0., 0., 0.), + const gp_XYZ& theAxis = gp_XYZ(0., 0., 1.), + const gp_XYZ& theRefDirection = gp_XYZ(0., 1., 0.)) const + { + const Handle(StepGeom_Plane) aPlane = new StepGeom_Plane; + const Handle(TCollection_HAsciiString) aName = + theName ? new TCollection_HAsciiString(theName) : new TCollection_HAsciiString(); + aPlane->Init(aName, addAxis2Placement3d(nullptr, theLocation, theAxis, theRefDirection)); + myWS->Model()->AddWithRefs(aPlane); + return aPlane; + } + + // Add an entity to the model. + // @param theEntity the entity to add. + void addToModel(const Handle(Standard_Transient)& theEntity) const + { + myWS->Model()->AddWithRefs(theEntity); + } + +protected: + Handle(XSControl_WorkSession) myWS; +}; + +#endif // _StepTidy_BaseTestFixture_HeaderFile diff --git a/src/DataExchange/TKDESTEP/GTests/StepTidy_CartesianPointReducer_Test.cxx b/src/DataExchange/TKDESTEP/GTests/StepTidy_CartesianPointReducer_Test.cxx new file mode 100644 index 0000000000..658d923cf6 --- /dev/null +++ b/src/DataExchange/TKDESTEP/GTests/StepTidy_CartesianPointReducer_Test.cxx @@ -0,0 +1,585 @@ +// 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 "StepTidy_BaseTestFixture.pxx" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class StepTidy_CartesianPointReducerTest : public StepTidy_BaseTestFixture +{ +protected: + // Perform removal of duplicate Cartesian points. + TColStd_MapOfTransient replaceDuplicateCartesianPoints() + { + StepTidy_CartesianPointReducer aReducer(myWS); + for (Standard_Integer anIndex = 1; anIndex <= myWS->Model()->NbEntities(); ++anIndex) + { + aReducer.ProcessEntity(myWS->Model()->Value(anIndex)); + } + + TColStd_MapOfTransient aRemovedEntities; + aReducer.Perform(aRemovedEntities); + return aRemovedEntities; + } +}; + +// Check that points with the same coordinates and different names are not merged. +TEST_F(StepTidy_CartesianPointReducerTest, DifferentNames) +{ + // Creating Cartesian points. + Handle(StepGeom_CartesianPoint) aPt1 = addCartesianPoint("FirstPt"); + Handle(StepGeom_CartesianPoint) aPt2 = addCartesianPoint("SecondPt"); + + // Creating direction. + Handle(TColStd_HArray1OfReal) aDirCoords = new TColStd_HArray1OfReal(1, 3); + aDirCoords->SetValue(1, 0.); + aDirCoords->SetValue(2, 0.); + aDirCoords->SetValue(3, 1.); + Handle(StepGeom_Direction) aDir = new StepGeom_Direction; + aDir->Init(new TCollection_HAsciiString, aDirCoords); + addToModel(aDir); + + // Creating axis containing the first Cartesian point. + Handle(StepGeom_Axis2Placement3d) aFirstAxis = new StepGeom_Axis2Placement3d; + aFirstAxis + ->Init(new TCollection_HAsciiString, aPt1, Standard_True, aDir, Standard_False, nullptr); + addToModel(aFirstAxis); + + // Creating axis containing the second Cartesian point. + Handle(StepGeom_Axis2Placement3d) aSecondAxis = new StepGeom_Axis2Placement3d; + aSecondAxis + ->Init(new TCollection_HAsciiString, aPt2, Standard_True, aDir, Standard_False, nullptr); + addToModel(aSecondAxis); + + // Performing removal of duplicate Cartesian points. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateCartesianPoints(); + + // Check that nothing was removed. + EXPECT_TRUE(aRemovedEntities.IsEmpty()); +} + +// Check that points with the same coordinates and same names are +// merged for StepGeom_Axis2Placement3d. +TEST_F(StepTidy_CartesianPointReducerTest, StepGeom_Axis2Placement3d) +{ + // Creating Cartesian points. + Handle(StepGeom_CartesianPoint) aPt1 = addCartesianPoint(); + Handle(StepGeom_CartesianPoint) aPt2 = addCartesianPoint(); + + // Creating direction. + Handle(TColStd_HArray1OfReal) aDirCoords = new TColStd_HArray1OfReal(1, 3); + aDirCoords->SetValue(1, 0.); + aDirCoords->SetValue(2, 0.); + aDirCoords->SetValue(3, 1.); + Handle(StepGeom_Direction) aDir = new StepGeom_Direction; + aDir->Init(new TCollection_HAsciiString, aDirCoords); + addToModel(aDir); + + // Creating axis containing the first Cartesian point. + Handle(StepGeom_Axis2Placement3d) aFirstAxis = new StepGeom_Axis2Placement3d; + aFirstAxis + ->Init(new TCollection_HAsciiString, aPt1, Standard_True, aDir, Standard_False, nullptr); + addToModel(aFirstAxis); + + // Creating axis containing the second Cartesian point. + Handle(StepGeom_Axis2Placement3d) aSecondAxis = new StepGeom_Axis2Placement3d; + aSecondAxis + ->Init(new TCollection_HAsciiString, aPt2, Standard_True, aDir, Standard_False, nullptr); + addToModel(aSecondAxis); + + // Performing removal of duplicate Cartesian points. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateCartesianPoints(); + + // Check that duplicate was removed. + EXPECT_EQ(aRemovedEntities.Size(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(aPt1) || aRemovedEntities.Contains(aPt2)); +} + +// Check that points with the same coordinates and same names are merged +// for StepShape_VertexPoint. +TEST_F(StepTidy_CartesianPointReducerTest, StepShape_VertexPoint) +{ + // Creating Cartesian points. + Handle(StepGeom_CartesianPoint) aPt1 = addCartesianPoint(); + Handle(StepGeom_CartesianPoint) aPt2 = addCartesianPoint(); + + // Creating vertex containing the first Cartesian point. + Handle(StepShape_VertexPoint) aFirstVertex = new StepShape_VertexPoint; + aFirstVertex->Init(new TCollection_HAsciiString, aPt1); + addToModel(aFirstVertex); + + // Creating vertex containing the second Cartesian point. + Handle(StepShape_VertexPoint) aSecondVertex = new StepShape_VertexPoint; + aSecondVertex->Init(new TCollection_HAsciiString, aPt2); + addToModel(aSecondVertex); + + // Performing removal of duplicate Cartesian points. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateCartesianPoints(); + + // Check that duplicate was removed. + EXPECT_EQ(aRemovedEntities.Size(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(aPt1) || aRemovedEntities.Contains(aPt2)); +} + +// Check that points with the same coordinates and same names are merged +// for StepShape_GeometricCurveSet. +TEST_F(StepTidy_CartesianPointReducerTest, StepShape_GeometricCurveSet) +{ + // Creating Cartesian points. + Handle(StepGeom_CartesianPoint) aPt1 = addCartesianPoint(); + Handle(StepGeom_CartesianPoint) aPt2 = addCartesianPoint(); + + // Creating curve set containing the first Cartesian point. + Handle(StepShape_HArray1OfGeometricSetSelect) aFirstElements = + new StepShape_HArray1OfGeometricSetSelect(1, 1); + StepShape_GeometricSetSelect aFirstSelect; + aFirstSelect.SetValue(aPt1); + aFirstElements->SetValue(1, aFirstSelect); + addToModel(aFirstElements); + Handle(StepShape_GeometricCurveSet) aFirstCurveSet = new StepShape_GeometricCurveSet; + aFirstCurveSet->Init(new TCollection_HAsciiString, aFirstElements); + addToModel(aFirstCurveSet); + + // Creating curve set containing the second Cartesian point. + Handle(StepShape_HArray1OfGeometricSetSelect) aSecondElements = + new StepShape_HArray1OfGeometricSetSelect(1, 1); + StepShape_GeometricSetSelect aSecondSelect; + aSecondSelect.SetValue(aPt2); + aSecondElements->SetValue(1, aSecondSelect); + addToModel(aSecondElements); + Handle(StepShape_GeometricCurveSet) aSecondCurveSet = new StepShape_GeometricCurveSet; + aSecondCurveSet->Init(new TCollection_HAsciiString, aSecondElements); + addToModel(aSecondCurveSet); + + // Performing removal of duplicate Cartesian points. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateCartesianPoints(); + + // Check that duplicate was removed. + EXPECT_EQ(aRemovedEntities.Size(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(aPt1) || aRemovedEntities.Contains(aPt2)); +} + +// Check that points with the same coordinates and same names are merged +// for StepVisual_PresentationLayerAssignment. +TEST_F(StepTidy_CartesianPointReducerTest, StepVisual_PresentationLayerAssignment) +{ + // Creating Cartesian points. + Handle(StepGeom_CartesianPoint) aPt1 = addCartesianPoint(); + Handle(StepGeom_CartesianPoint) aPt2 = addCartesianPoint(); + + // Creating presentation layer assignment containing the first Cartesian point. + Handle(StepVisual_HArray1OfLayeredItem) aFirstAssignedItems = + new StepVisual_HArray1OfLayeredItem(1, 1); + StepVisual_LayeredItem aFirstLayeredItem; + aFirstLayeredItem.SetValue(aPt1); + aFirstAssignedItems->SetValue(1, aFirstLayeredItem); + addToModel(aFirstAssignedItems); + Handle(StepVisual_PresentationLayerAssignment) aFirstAssignment = + new StepVisual_PresentationLayerAssignment; + aFirstAssignment->Init(new TCollection_HAsciiString, + new TCollection_HAsciiString, + aFirstAssignedItems); + addToModel(aFirstAssignment); + + // Creating presentation layer assignment containing the second Cartesian point. + Handle(StepVisual_HArray1OfLayeredItem) aSecondAssignedItems = + new StepVisual_HArray1OfLayeredItem(1, 1); + StepVisual_LayeredItem aSecondLayeredItem; + aSecondLayeredItem.SetValue(aPt2); + aSecondAssignedItems->SetValue(1, aSecondLayeredItem); + addToModel(aSecondAssignedItems); + Handle(StepVisual_PresentationLayerAssignment) aSecondAssignment = + new StepVisual_PresentationLayerAssignment; + aSecondAssignment->Init(new TCollection_HAsciiString, + new TCollection_HAsciiString, + aSecondAssignedItems); + addToModel(aSecondAssignment); + + // Performing removal of duplicate Cartesian points. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateCartesianPoints(); + + // Check that duplicate was removed. + EXPECT_EQ(aRemovedEntities.Size(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(aPt1) || aRemovedEntities.Contains(aPt2)); +} + +// Check that points with the same coordinates and same names are merged +// for StepVisual_StyledItem. +TEST_F(StepTidy_CartesianPointReducerTest, StepVisual_StyledItem) +{ + // Creating Cartesian points. + Handle(StepGeom_CartesianPoint) aPt1 = addCartesianPoint(); + Handle(StepGeom_CartesianPoint) aPt2 = addCartesianPoint(); + + // Creating styled item containing the first Cartesian point. + Handle(StepVisual_HArray1OfPresentationStyleAssignment) aFirstAssignedItems = + new StepVisual_HArray1OfPresentationStyleAssignment(1, 1); + Handle(StepVisual_StyledItem) aFirstStyledItem = new StepVisual_StyledItem; + aFirstStyledItem->Init(new TCollection_HAsciiString, aFirstAssignedItems, aPt1); + addToModel(aFirstStyledItem); + + // Creating styled item containing the second Cartesian point. + Handle(StepVisual_HArray1OfPresentationStyleAssignment) aSecondAssignedItems = + new StepVisual_HArray1OfPresentationStyleAssignment(1, 1); + Handle(StepVisual_StyledItem) aSecondStyledItem = new StepVisual_StyledItem; + aSecondStyledItem->Init(new TCollection_HAsciiString, aSecondAssignedItems, aPt2); + addToModel(aSecondStyledItem); + + // Performing removal of duplicate Cartesian points. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateCartesianPoints(); + + // Check that duplicate was removed. + EXPECT_EQ(aRemovedEntities.Size(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(aPt1) || aRemovedEntities.Contains(aPt2)); +} + +// Check that points with the same coordinates and same names are merged +// for StepGeom_BSplineCurveWithKnots. +TEST_F(StepTidy_CartesianPointReducerTest, StepGeom_BSplineCurveWithKnots) +{ + // Creating Cartesian points. + Handle(StepGeom_CartesianPoint) aPt1 = addCartesianPoint(); + Handle(StepGeom_CartesianPoint) aPt2 = addCartesianPoint(); + + // Creating curve containing the first Cartesian point. + Handle(StepGeom_HArray1OfCartesianPoint) aFirstControlPoints = + new StepGeom_HArray1OfCartesianPoint(1, 1); + aFirstControlPoints->SetValue(1, aPt1); + Handle(StepGeom_BSplineCurveWithKnots) aFirstCurve = new StepGeom_BSplineCurveWithKnots; + aFirstCurve->Init(new TCollection_HAsciiString, + 1, + aFirstControlPoints, + StepGeom_bscfUnspecified, + StepData_LUnknown, + StepData_LUnknown, + new TColStd_HArray1OfInteger, + new TColStd_HArray1OfReal, + StepGeom_ktUnspecified); + addToModel(aFirstCurve); + + // Creating curve containing the second Cartesian point. + Handle(StepGeom_HArray1OfCartesianPoint) aSecondControlPoints = + new StepGeom_HArray1OfCartesianPoint(1, 1); + aSecondControlPoints->SetValue(1, aPt2); + Handle(StepGeom_BSplineCurveWithKnots) aSecondCurve = new StepGeom_BSplineCurveWithKnots; + aSecondCurve->Init(new TCollection_HAsciiString, + 1, + aSecondControlPoints, + StepGeom_bscfUnspecified, + StepData_LUnknown, + StepData_LUnknown, + new TColStd_HArray1OfInteger, + new TColStd_HArray1OfReal, + StepGeom_ktUnspecified); + addToModel(aSecondCurve); + + // Performing removal of duplicate Cartesian points. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateCartesianPoints(); + + // Check that duplicate was removed. + EXPECT_EQ(aRemovedEntities.Size(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(aPt1) || aRemovedEntities.Contains(aPt2)); +} + +// Check that points with the same coordinates and same names are merged +// for StepGeom_Line. +TEST_F(StepTidy_CartesianPointReducerTest, StepGeom_Line) +{ + // Creating Cartesian points. + Handle(StepGeom_CartesianPoint) aPt1 = addCartesianPoint(); + Handle(StepGeom_CartesianPoint) aPt2 = addCartesianPoint(); + + // Creating line containing the first Cartesian point. + Handle(StepGeom_Line) aFirstLine = new StepGeom_Line; + aFirstLine->Init(new TCollection_HAsciiString, aPt1, new StepGeom_Vector); + addToModel(aFirstLine); + + // Creating line containing the second Cartesian point. + Handle(StepGeom_Line) aSecondLine = new StepGeom_Line; + aSecondLine->Init(new TCollection_HAsciiString, aPt2, new StepGeom_Vector); + addToModel(aSecondLine); + + // Performing removal of duplicate Cartesian points. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateCartesianPoints(); + + // Check that duplicate was removed. + EXPECT_EQ(aRemovedEntities.Size(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(aPt1) || aRemovedEntities.Contains(aPt2)); +} + +// Check that points with the same coordinates and same names are merged +// for StepGeom_BSplineSurfaceWithKnots. +TEST_F(StepTidy_CartesianPointReducerTest, StepGeom_BSplineSurfaceWithKnots) +{ + // Creating Cartesian points. + Handle(StepGeom_CartesianPoint) aPt1 = addCartesianPoint(); + Handle(StepGeom_CartesianPoint) aPt2 = addCartesianPoint(); + + // Creating surface containing the first Cartesian point. + Handle(StepGeom_HArray2OfCartesianPoint) aFirstControlPoints = + new StepGeom_HArray2OfCartesianPoint(1, 1, 1, 1); + aFirstControlPoints->SetValue(1, 1, aPt1); + Handle(StepGeom_BSplineSurfaceWithKnots) aFirstSurface = new StepGeom_BSplineSurfaceWithKnots; + aFirstSurface->Init(new TCollection_HAsciiString, + 1, + 1, + aFirstControlPoints, + StepGeom_bssfUnspecified, + StepData_LUnknown, + StepData_LUnknown, + StepData_LUnknown, + new TColStd_HArray1OfInteger, + new TColStd_HArray1OfInteger, + new TColStd_HArray1OfReal, + new TColStd_HArray1OfReal, + StepGeom_ktUnspecified); + addToModel(aFirstSurface); + + // Creating surface containing the second Cartesian point. + Handle(StepGeom_HArray2OfCartesianPoint) aSecondControlPoints = + new StepGeom_HArray2OfCartesianPoint(1, 1, 1, 1); + aSecondControlPoints->SetValue(1, 1, aPt2); + Handle(StepGeom_BSplineSurfaceWithKnots) aSecondSurface = new StepGeom_BSplineSurfaceWithKnots; + aSecondSurface->Init(new TCollection_HAsciiString, + 1, + 1, + aSecondControlPoints, + StepGeom_bssfUnspecified, + StepData_LUnknown, + StepData_LUnknown, + StepData_LUnknown, + new TColStd_HArray1OfInteger, + new TColStd_HArray1OfInteger, + new TColStd_HArray1OfReal, + new TColStd_HArray1OfReal, + StepGeom_ktUnspecified); + addToModel(aSecondSurface); + + // Performing removal of duplicate Cartesian points. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateCartesianPoints(); + + // Check that duplicate was removed. + EXPECT_EQ(aRemovedEntities.Size(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(aPt1) || aRemovedEntities.Contains(aPt2)); +} + +// Check that points with the same coordinates and same names are merged +// for StepGeom_Axis1Placement. +TEST_F(StepTidy_CartesianPointReducerTest, StepGeom_Axis1Placement) +{ + // Creating Cartesian points. + Handle(StepGeom_CartesianPoint) aPt1 = addCartesianPoint(); + Handle(StepGeom_CartesianPoint) aPt2 = addCartesianPoint(); + + // Creating axis containing the first Cartesian point. + Handle(StepGeom_Axis1Placement) aFirstAxis = new StepGeom_Axis1Placement; + aFirstAxis->Init(new TCollection_HAsciiString, aPt1, false, new StepGeom_Direction); + addToModel(aFirstAxis); + + // Creating axis containing the second Cartesian point. + Handle(StepGeom_Axis1Placement) aSecondAxis = new StepGeom_Axis1Placement; + aSecondAxis->Init(new TCollection_HAsciiString, aPt2, false, new StepGeom_Direction); + addToModel(aSecondAxis); + + // Performing removal of duplicate Cartesian points. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateCartesianPoints(); + + // Check that duplicate was removed. + EXPECT_EQ(aRemovedEntities.Size(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(aPt1) || aRemovedEntities.Contains(aPt2)); +} + +// Check that points with the same coordinates and same names are merged +// for StepRepr_Representation. +TEST_F(StepTidy_CartesianPointReducerTest, StepRepr_Representation) +{ + // Creating Cartesian points. + Handle(StepGeom_CartesianPoint) aPt1 = addCartesianPoint(); + Handle(StepGeom_CartesianPoint) aPt2 = addCartesianPoint(); + + // Creating representation containing the first Cartesian point. + Handle(StepRepr_HArray1OfRepresentationItem) aFirstItems = + new StepRepr_HArray1OfRepresentationItem(1, 1); + aFirstItems->SetValue(1, aPt1); + Handle(StepRepr_Representation) aFirstRepresentation = new StepRepr_Representation; + aFirstRepresentation->Init(new TCollection_HAsciiString, + aFirstItems, + new StepRepr_RepresentationContext); + addToModel(aFirstRepresentation); + + // Creating representation containing the second Cartesian point. + Handle(StepRepr_HArray1OfRepresentationItem) aSecondItems = + new StepRepr_HArray1OfRepresentationItem(1, 1); + aSecondItems->SetValue(1, aPt2); + Handle(StepRepr_Representation) aSecondRepresentation = new StepRepr_Representation; + aSecondRepresentation->Init(new TCollection_HAsciiString, + aSecondItems, + new StepRepr_RepresentationContext); + addToModel(aSecondRepresentation); + + // Performing removal of duplicate Cartesian points. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateCartesianPoints(); + + // Check that duplicate was removed. + EXPECT_EQ(aRemovedEntities.Size(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(aPt1) || aRemovedEntities.Contains(aPt2)); +} + +// Check that points with the same coordinates and same names are merged +// for StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve. +TEST_F(StepTidy_CartesianPointReducerTest, StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve) +{ + // Creating Cartesian points. + Handle(StepGeom_CartesianPoint) aPt1 = addCartesianPoint(); + Handle(StepGeom_CartesianPoint) aPt2 = addCartesianPoint(); + + // Creating curve containing the first Cartesian point. + Handle(StepGeom_HArray1OfCartesianPoint) aFirstControlPoints = + new StepGeom_HArray1OfCartesianPoint(1, 1); + aFirstControlPoints->SetValue(1, aPt1); + Handle(StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve) aFirstCurve = + new StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve; + aFirstCurve->Init(new TCollection_HAsciiString, + 1, + aFirstControlPoints, + StepGeom_bscfUnspecified, + StepData_LUnknown, + StepData_LUnknown, + new TColStd_HArray1OfInteger, + new TColStd_HArray1OfReal, + StepGeom_ktUnspecified, + new TColStd_HArray1OfReal); + addToModel(aFirstCurve); + + // Creating curve containing the second Cartesian point. + Handle(StepGeom_HArray1OfCartesianPoint) aSecondControlPoints = + new StepGeom_HArray1OfCartesianPoint(1, 1); + aSecondControlPoints->SetValue(1, aPt2); + Handle(StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve) aSecondCurve = + new StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve; + aSecondCurve->Init(new TCollection_HAsciiString, + 1, + aSecondControlPoints, + StepGeom_bscfUnspecified, + StepData_LUnknown, + StepData_LUnknown, + new TColStd_HArray1OfInteger, + new TColStd_HArray1OfReal, + StepGeom_ktUnspecified, + new TColStd_HArray1OfReal); + addToModel(aSecondCurve); + + // Performing removal of duplicate Cartesian points. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateCartesianPoints(); + + // Check that duplicate was removed. + EXPECT_EQ(aRemovedEntities.Size(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(aPt1) || aRemovedEntities.Contains(aPt2)); +} + +// Check that points with the same coordinates and same names are merged +// for StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface. +TEST_F(StepTidy_CartesianPointReducerTest, + StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface) +{ + // Creating Cartesian points. + Handle(StepGeom_CartesianPoint) aPt1 = addCartesianPoint(); + Handle(StepGeom_CartesianPoint) aPt2 = addCartesianPoint(); + + // Creating surface containing the first Cartesian point. + Handle(StepGeom_HArray2OfCartesianPoint) aFirstControlPoints = + new StepGeom_HArray2OfCartesianPoint(1, 1, 1, 1); + aFirstControlPoints->SetValue(1, 1, aPt1); + Handle(StepGeom_BSplineSurfaceWithKnots) aFirstBSSWN = new StepGeom_BSplineSurfaceWithKnots; + aFirstBSSWN->Init(new TCollection_HAsciiString, + 1, + 1, + aFirstControlPoints, + StepGeom_bssfUnspecified, + StepData_LUnknown, + StepData_LUnknown, + StepData_LUnknown, + new TColStd_HArray1OfInteger, + new TColStd_HArray1OfInteger, + new TColStd_HArray1OfReal, + new TColStd_HArray1OfReal, + StepGeom_ktUnspecified); + addToModel(aFirstBSSWN); + Handle(StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface) aFirstSurface = + new StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface; + aFirstSurface->Init(new TCollection_HAsciiString, + 1, + 1, + aFirstControlPoints, + StepGeom_bssfUnspecified, + StepData_LUnknown, + StepData_LUnknown, + StepData_LUnknown, + aFirstBSSWN, + new StepGeom_RationalBSplineSurface); + addToModel(aFirstSurface); + + // Creating surface containing the second Cartesian point. + Handle(StepGeom_HArray2OfCartesianPoint) aSecondControlPoints = + new StepGeom_HArray2OfCartesianPoint(1, 1, 1, 1); + aSecondControlPoints->SetValue(1, 1, aPt2); + Handle(StepGeom_BSplineSurfaceWithKnots) aSecondBSSWN = new StepGeom_BSplineSurfaceWithKnots; + aSecondBSSWN->Init(new TCollection_HAsciiString, + 1, + 1, + aSecondControlPoints, + StepGeom_bssfUnspecified, + StepData_LUnknown, + StepData_LUnknown, + StepData_LUnknown, + new TColStd_HArray1OfInteger, + new TColStd_HArray1OfInteger, + new TColStd_HArray1OfReal, + new TColStd_HArray1OfReal, + StepGeom_ktUnspecified); + addToModel(aSecondBSSWN); + Handle(StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface) aSecondSurface = + new StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface; + aSecondSurface->Init(new TCollection_HAsciiString, + 1, + 1, + aSecondControlPoints, + StepGeom_bssfUnspecified, + StepData_LUnknown, + StepData_LUnknown, + StepData_LUnknown, + new StepGeom_BSplineSurfaceWithKnots, + new StepGeom_RationalBSplineSurface); + + // Performing removal of duplicate Cartesian points. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateCartesianPoints(); + + // Check that duplicate was removed. + EXPECT_EQ(aRemovedEntities.Size(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(aPt1) || aRemovedEntities.Contains(aPt2)); +} diff --git a/src/DataExchange/TKDESTEP/GTests/StepTidy_CircleReducer_Test.cxx b/src/DataExchange/TKDESTEP/GTests/StepTidy_CircleReducer_Test.cxx new file mode 100644 index 0000000000..f2541a75f6 --- /dev/null +++ b/src/DataExchange/TKDESTEP/GTests/StepTidy_CircleReducer_Test.cxx @@ -0,0 +1,165 @@ +// 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 "StepTidy_BaseTestFixture.pxx" + +#include + +#include +#include +#include + +class StepTidy_CircleReducerTest : public StepTidy_BaseTestFixture +{ +protected: + //! Perform removal of duplicate entities. + TColStd_MapOfTransient replaceDuplicateCircles() + { + StepTidy_CircleReducer aReducer(myWS); + for (Standard_Integer anIndex = 1; anIndex <= myWS->Model()->NbEntities(); ++anIndex) + { + aReducer.ProcessEntity(myWS->Model()->Value(anIndex)); + } + + TColStd_MapOfTransient aRemovedEntities; + aReducer.Perform(aRemovedEntities); + return aRemovedEntities; + } +}; + +// Check that Circles with the same coordinates and different names are not merged. +TEST_F(StepTidy_CircleReducerTest, DifferentNames) +{ + // Creating Circles. + Handle(StepGeom_Circle) aCircle1 = addCircle("Circle1"); + Handle(StepGeom_Circle) aCircle2 = addCircle("Circle2"); + + // Creating EdgeCurve containing the first Circle. + Handle(StepShape_EdgeCurve) aFirstEdgeCurve = new StepShape_EdgeCurve; + aFirstEdgeCurve->Init(new TCollection_HAsciiString, + new StepShape_Vertex, + new StepShape_Vertex, + aCircle1, + Standard_True); + addToModel(aFirstEdgeCurve); + + // Creating EdgeCurve containing the second Circle. + Handle(StepShape_EdgeCurve) aSecondEdgeCurve = new StepShape_EdgeCurve; + aSecondEdgeCurve->Init(new TCollection_HAsciiString, + new StepShape_Vertex, + new StepShape_Vertex, + aCircle2, + Standard_True); + addToModel(aSecondEdgeCurve); + + // Performing removal of duplicate Circles. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateCircles(); + + // Check that nothing was removed. + EXPECT_TRUE(aRemovedEntities.IsEmpty()); +} + +// Check that equal Circles are merged for StepShape_EdgeCurve. +TEST_F(StepTidy_CircleReducerTest, StepShape_EdgeCurve) +{ + // Creating Circles. + Handle(StepGeom_Circle) aCircle1 = addCircle(); + Handle(StepGeom_Circle) aCircle2 = addCircle(); + + // Creating EdgeCurve containing the first Circle. + Handle(StepShape_EdgeCurve) aFirstEdgeCurve = new StepShape_EdgeCurve; + aFirstEdgeCurve->Init(new TCollection_HAsciiString, + new StepShape_Vertex, + new StepShape_Vertex, + aCircle1, + Standard_True); + addToModel(aFirstEdgeCurve); + + // Creating EdgeCurve containing the second Circle. + Handle(StepShape_EdgeCurve) aSecondEdgeCurve = new StepShape_EdgeCurve; + aSecondEdgeCurve->Init(new TCollection_HAsciiString, + new StepShape_Vertex, + new StepShape_Vertex, + aCircle2, + Standard_True); + addToModel(aSecondEdgeCurve); + + // Performing removal of duplicate Circles. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateCircles(); + + // Check that one Circle was removed. + EXPECT_EQ(aRemovedEntities.Size(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(aCircle1) || aRemovedEntities.Contains(aCircle2)); +} + +// Check that equal Circles are merged for StepGeom_SurfaceCurve. +TEST_F(StepTidy_CircleReducerTest, StepGeom_SurfaceCurve) +{ + // Creating Circles. + Handle(StepGeom_Circle) aCircle1 = addCircle(); + Handle(StepGeom_Circle) aCircle2 = addCircle(); + + // Creating SurfaceCurve containing the first Circle. + Handle(StepGeom_SurfaceCurve) aFirstSurfaceCurve = new StepGeom_SurfaceCurve; + aFirstSurfaceCurve->Init(new TCollection_HAsciiString, + aCircle1, + new StepGeom_HArray1OfPcurveOrSurface, + StepGeom_pscrCurve3d); + addToModel(aFirstSurfaceCurve); + + // Creating SurfaceCurve containing the second Circle. + Handle(StepGeom_SurfaceCurve) aSecondSurfaceCurve = new StepGeom_SurfaceCurve; + aSecondSurfaceCurve->Init(new TCollection_HAsciiString, + aCircle2, + new StepGeom_HArray1OfPcurveOrSurface, + StepGeom_pscrCurve3d); + addToModel(aSecondSurfaceCurve); + + // Performing removal of duplicate Circles. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateCircles(); + + // Check that one Circle was removed. + EXPECT_EQ(aRemovedEntities.Size(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(aCircle1) || aRemovedEntities.Contains(aCircle2)); +} + +// Check that equal Circles are merged for StepGeom_SeamCurve. +TEST_F(StepTidy_CircleReducerTest, StepGeom_SeamCurve) +{ + // Creating Circles. + Handle(StepGeom_Circle) aCircle1 = addCircle(); + Handle(StepGeom_Circle) aCircle2 = addCircle(); + + // Creating SeamCurve containing the first Circle. + Handle(StepGeom_SeamCurve) aFirstSeamCurve = new StepGeom_SeamCurve; + aFirstSeamCurve->Init(new TCollection_HAsciiString, + aCircle1, + new StepGeom_HArray1OfPcurveOrSurface, + StepGeom_pscrCurve3d); + addToModel(aFirstSeamCurve); + + // Creating SeamCurve containing the second Circle. + Handle(StepGeom_SeamCurve) aSecondSeamCurve = new StepGeom_SeamCurve; + aSecondSeamCurve->Init(new TCollection_HAsciiString, + aCircle2, + new StepGeom_HArray1OfPcurveOrSurface, + StepGeom_pscrCurve3d); + addToModel(aSecondSeamCurve); + + // Performing removal of duplicate Circles. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateCircles(); + + // Check that one Circle was removed. + EXPECT_EQ(aRemovedEntities.Size(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(aCircle1) || aRemovedEntities.Contains(aCircle2)); +} diff --git a/src/DataExchange/TKDESTEP/GTests/StepTidy_DirectionReducer_Test.cxx b/src/DataExchange/TKDESTEP/GTests/StepTidy_DirectionReducer_Test.cxx new file mode 100644 index 0000000000..9b32c3394e --- /dev/null +++ b/src/DataExchange/TKDESTEP/GTests/StepTidy_DirectionReducer_Test.cxx @@ -0,0 +1,157 @@ +// 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 "StepTidy_BaseTestFixture.pxx" + +#include + +#include +#include + +class StepTidy_DirectionReducerTest : public StepTidy_BaseTestFixture +{ +protected: + //! Perform removal of duplicate entities. + TColStd_MapOfTransient replaceDuplicateDirections() + { + StepTidy_DirectionReducer aReducer(myWS); + for (Standard_Integer anIndex = 1; anIndex <= myWS->Model()->NbEntities(); ++anIndex) + { + aReducer.ProcessEntity(myWS->Model()->Value(anIndex)); + } + + TColStd_MapOfTransient aRemovedEntities; + aReducer.Perform(aRemovedEntities); + return aRemovedEntities; + } +}; + +// Check that directions with the same coordinates and different names are not merged. +TEST_F(StepTidy_DirectionReducerTest, DifferentNames) +{ + // Creating directions. + Handle(StepGeom_Direction) aDir1 = addDirection("dir1"); + Handle(StepGeom_Direction) aDir2 = addDirection("dir2"); + + // Creating vector containing the first direction. + Handle(StepGeom_Vector) aFirstVector = new StepGeom_Vector; + aFirstVector->Init(new TCollection_HAsciiString, aDir1, 1.); + addToModel(aFirstVector); + + // Creating vector containing the second direction. + Handle(StepGeom_Vector) aSecondVector = new StepGeom_Vector; + aSecondVector->Init(new TCollection_HAsciiString, aDir2, 1.); + addToModel(aSecondVector); + + // Performing removal of duplicate directions. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateDirections(); + + // Check that nothing was removed. + EXPECT_TRUE(aRemovedEntities.IsEmpty()); +} + +// Check that directions with the same coordinates and same names are +// merged for StepGeom_Axis1Placement. +TEST_F(StepTidy_DirectionReducerTest, StepGeom_Axis1Placement) +{ + // Creating directions. + Handle(StepGeom_Direction) aDir1 = addDirection(); + Handle(StepGeom_Direction) aDir2 = addDirection(); + + // Creating Cartesian point for the location. + Handle(StepGeom_CartesianPoint) aLocation = new StepGeom_CartesianPoint; + Handle(TColStd_HArray1OfReal) aLocationCoords = new TColStd_HArray1OfReal(1, 3); + aLocationCoords->SetValue(1, 0.); + aLocationCoords->SetValue(2, 0.); + aLocationCoords->SetValue(3, 0.); + aLocation->Init(new TCollection_HAsciiString, aLocationCoords); + addToModel(aLocation); + + // Creating axis containing the first direction. + Handle(StepGeom_Axis1Placement) aFirstAxis = new StepGeom_Axis1Placement; + aFirstAxis->Init(new TCollection_HAsciiString, aLocation, true, aDir1); + addToModel(aFirstAxis); + + // Creating axis containing the second direction. + Handle(StepGeom_Axis1Placement) aSecondAxis = new StepGeom_Axis1Placement; + aSecondAxis->Init(new TCollection_HAsciiString, aLocation, true, aDir2); + addToModel(aSecondAxis); + + // Performing removal of duplicate Cartesian points. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateDirections(); + + // Check that duplicate was removed. + EXPECT_EQ(aRemovedEntities.Size(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(aDir1) || aRemovedEntities.Contains(aDir2)); +} + +// Check that directions with the same coordinates and same names are +// merged for StepGeom_Axis2Placement. +TEST_F(StepTidy_DirectionReducerTest, StepGeom_Axis2Placement) +{ + // Creating directions. + Handle(StepGeom_Direction) aDir1 = addDirection(); + Handle(StepGeom_Direction) aDir2 = addDirection(); + + // Creating Cartesian point for the location. + Handle(StepGeom_CartesianPoint) aLocation = new StepGeom_CartesianPoint; + Handle(TColStd_HArray1OfReal) aLocationCoords = new TColStd_HArray1OfReal(1, 3); + aLocationCoords->SetValue(1, 0.); + aLocationCoords->SetValue(2, 0.); + aLocationCoords->SetValue(3, 0.); + aLocation->Init(new TCollection_HAsciiString, aLocationCoords); + addToModel(aLocation); + + // Creating axis containing the first direction. + Handle(StepGeom_Axis2Placement3d) aFirstAxis = new StepGeom_Axis2Placement3d; + aFirstAxis->Init(new TCollection_HAsciiString, aLocation, true, aDir1, false, nullptr); + addToModel(aFirstAxis); + + // Creating axis containing the second direction. + Handle(StepGeom_Axis2Placement3d) aSecondAxis = new StepGeom_Axis2Placement3d; + aSecondAxis->Init(new TCollection_HAsciiString, aLocation, true, aDir2, false, nullptr); + addToModel(aSecondAxis); + + // Performing removal of duplicate Cartesian points. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateDirections(); + + // Check that duplicate was removed. + EXPECT_EQ(aRemovedEntities.Size(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(aDir1) || aRemovedEntities.Contains(aDir2)); +} + +// Check that points with the same coordinates and same names are +// merged for StepGeom_Vector. +TEST_F(StepTidy_DirectionReducerTest, StepGeom_Vector) +{ + // Creating directions. + Handle(StepGeom_Direction) aDir1 = addDirection(); + Handle(StepGeom_Direction) aDir2 = addDirection(); + + // Creating vector containing the first direction. + Handle(StepGeom_Vector) aFirstVector = new StepGeom_Vector; + aFirstVector->Init(new TCollection_HAsciiString, aDir1, 1.); + addToModel(aFirstVector); + + // Creating vector containing the second direction. + Handle(StepGeom_Vector) aSecondVector = new StepGeom_Vector; + aSecondVector->Init(new TCollection_HAsciiString, aDir2, 1.); + addToModel(aSecondVector); + + // Performing removal of duplicate Cartesian points. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateDirections(); + + // Check that duplicate was removed. + EXPECT_EQ(aRemovedEntities.Size(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(aDir1) || aRemovedEntities.Contains(aDir2)); +} diff --git a/src/DataExchange/TKDESTEP/GTests/StepTidy_LineReducer_Test.cxx b/src/DataExchange/TKDESTEP/GTests/StepTidy_LineReducer_Test.cxx new file mode 100644 index 0000000000..79e8f8cc3f --- /dev/null +++ b/src/DataExchange/TKDESTEP/GTests/StepTidy_LineReducer_Test.cxx @@ -0,0 +1,239 @@ +// 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 "StepTidy_BaseTestFixture.pxx" + +#include + +#include +#include +#include +#include +#include +#include + +class StepTidy_LineReducerTest : public StepTidy_BaseTestFixture +{ +protected: + //! Perform removal of duplicate entities. + TColStd_MapOfTransient replaceDuplicateLines() + { + StepTidy_LineReducer aReducer(myWS); + for (Standard_Integer anIndex = 1; anIndex <= myWS->Model()->NbEntities(); ++anIndex) + { + aReducer.ProcessEntity(myWS->Model()->Value(anIndex)); + } + + TColStd_MapOfTransient aRemovedEntities; + aReducer.Perform(aRemovedEntities); + return aRemovedEntities; + } +}; + +// Check that Lines with different names are not merged. +TEST_F(StepTidy_LineReducerTest, DifferentNames) +{ + // Creating Lines. + Handle(StepGeom_Line) aLine1 = addLine("Line1"); + Handle(StepGeom_Line) aLine2 = addLine("Line2"); + + // Creating EdgeCurve containing the first Line. + Handle(StepShape_EdgeCurve) aFirstEdgeCurve = new StepShape_EdgeCurve; + aFirstEdgeCurve->Init(new TCollection_HAsciiString, + new StepShape_Vertex, + new StepShape_Vertex, + aLine1, + Standard_True); + addToModel(aFirstEdgeCurve); + + // Creating EdgeCurve containing the second Line. + Handle(StepShape_EdgeCurve) aSecondEdgeCurve = new StepShape_EdgeCurve; + aSecondEdgeCurve->Init(new TCollection_HAsciiString, + new StepShape_Vertex, + new StepShape_Vertex, + aLine2, + Standard_True); + addToModel(aSecondEdgeCurve); + + // Performing removal of duplicate Lines. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateLines(); + + // Check that nothing was removed. + EXPECT_TRUE(aRemovedEntities.IsEmpty()); +} + +// Check that equal Lines are merged for StepShape_EdgeCurve. +TEST_F(StepTidy_LineReducerTest, StepShape_EdgeCurve) +{ + // Creating Lines. + Handle(StepGeom_Line) aLine1 = addLine(); + Handle(StepGeom_Line) aLine2 = addLine(); + + // Creating EdgeCurve containing the first Line. + Handle(StepShape_EdgeCurve) aFirstEdgeCurve = new StepShape_EdgeCurve; + aFirstEdgeCurve->Init(new TCollection_HAsciiString, + new StepShape_Vertex, + new StepShape_Vertex, + aLine1, + Standard_True); + addToModel(aFirstEdgeCurve); + + // Creating EdgeCurve containing the second Line. + Handle(StepShape_EdgeCurve) aSecondEdgeCurve = new StepShape_EdgeCurve; + aSecondEdgeCurve->Init(new TCollection_HAsciiString, + new StepShape_Vertex, + new StepShape_Vertex, + aLine2, + Standard_True); + addToModel(aSecondEdgeCurve); + + // Performing removal of duplicate Lines. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateLines(); + + // Check that one Line was removed. + EXPECT_EQ(aRemovedEntities.Size(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(aLine1) || aRemovedEntities.Contains(aLine2)); +} + +// Check that equal Lines are merged for StepGeom_TrimmedCurve. +TEST_F(StepTidy_LineReducerTest, StepGeom_TrimmedCurve) +{ + // Creating Lines. + Handle(StepGeom_Line) aLine1 = addLine(); + Handle(StepGeom_Line) aLine2 = addLine(); + + // Creating TrimmedCurve containing the first Line. + Handle(StepGeom_TrimmedCurve) aFirstTrimmedCurve = new StepGeom_TrimmedCurve; + aFirstTrimmedCurve->Init(new TCollection_HAsciiString, + aLine1, + new StepGeom_HArray1OfTrimmingSelect, + new StepGeom_HArray1OfTrimmingSelect, + Standard_True, + StepGeom_tpUnspecified); + addToModel(aFirstTrimmedCurve); + + // Creating TrimmedCurve containing the second Line. + Handle(StepGeom_TrimmedCurve) aSecondTrimmedCurve = new StepGeom_TrimmedCurve; + aSecondTrimmedCurve->Init(new TCollection_HAsciiString, + aLine2, + new StepGeom_HArray1OfTrimmingSelect, + new StepGeom_HArray1OfTrimmingSelect, + Standard_True, + StepGeom_tpUnspecified); + addToModel(aSecondTrimmedCurve); + + // Performing removal of duplicate Lines. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateLines(); + + // Check that one Line was removed. + EXPECT_EQ(aRemovedEntities.Size(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(aLine1) || aRemovedEntities.Contains(aLine2)); +} + +// Check that equal Lines are merged for StepGeom_SurfaceCurve. +TEST_F(StepTidy_LineReducerTest, StepGeom_SurfaceCurve) +{ + // Creating Lines. + Handle(StepGeom_Line) aLine1 = addLine(); + Handle(StepGeom_Line) aLine2 = addLine(); + + // Creating SurfaceCurve containing the first Line. + Handle(StepGeom_SurfaceCurve) aFirstSurfaceCurve = new StepGeom_SurfaceCurve; + aFirstSurfaceCurve->Init(new TCollection_HAsciiString, + aLine1, + new StepGeom_HArray1OfPcurveOrSurface, + StepGeom_pscrCurve3d); + addToModel(aFirstSurfaceCurve); + + // Creating SurfaceCurve containing the second Line. + Handle(StepGeom_SurfaceCurve) aSecondSurfaceCurve = new StepGeom_SurfaceCurve; + aSecondSurfaceCurve->Init(new TCollection_HAsciiString, + aLine2, + new StepGeom_HArray1OfPcurveOrSurface, + StepGeom_pscrCurve3d); + addToModel(aSecondSurfaceCurve); + + // Performing removal of duplicate Lines. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateLines(); + + // Check that one Line was removed. + EXPECT_EQ(aRemovedEntities.Size(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(aLine1) || aRemovedEntities.Contains(aLine2)); +} + +// Check that equal Lines are merged for StepRepr_DefinitionalRepresentation. +TEST_F(StepTidy_LineReducerTest, StepRepr_DefinitionalRepresentation) +{ + // Creating Lines. + Handle(StepGeom_Line) aLine1 = addLine(); + Handle(StepGeom_Line) aLine2 = addLine(); + + // Creating DefinitionalRepresentation containing the first Line. + Handle(StepRepr_HArray1OfRepresentationItem) aFirstItems = + new StepRepr_HArray1OfRepresentationItem(1, 1); + aFirstItems->SetValue(1, aLine1); + Handle(StepRepr_DefinitionalRepresentation) aFirstDefinitionalRepresentation = + new StepRepr_DefinitionalRepresentation; + aFirstDefinitionalRepresentation->Init(new TCollection_HAsciiString, + aFirstItems, + new StepRepr_RepresentationContext); + addToModel(aFirstDefinitionalRepresentation); + + // Creating DefinitionalRepresentation containing the second Line. + Handle(StepRepr_HArray1OfRepresentationItem) aSecondItems = + new StepRepr_HArray1OfRepresentationItem(1, 1); + aSecondItems->SetValue(1, aLine2); + Handle(StepRepr_DefinitionalRepresentation) aSecondDefinitionalRepresentation = + new StepRepr_DefinitionalRepresentation; + aSecondDefinitionalRepresentation->Init(new TCollection_HAsciiString, + aSecondItems, + new StepRepr_RepresentationContext); + + // Performing removal of duplicate Lines. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateLines(); + + // Check that one Line was removed. + EXPECT_EQ(aRemovedEntities.Size(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(aLine1) || aRemovedEntities.Contains(aLine2)); +} + +// Check that equal Lines are merged for StepGeom_SeamCurve. +TEST_F(StepTidy_LineReducerTest, StepGeom_SeamCurve) +{ + // Creating Lines. + Handle(StepGeom_Line) aLine1 = addLine(); + Handle(StepGeom_Line) aLine2 = addLine(); + + // Creating SeamCurve containing the first Line. + Handle(StepGeom_SeamCurve) aFirstSeamCurve = new StepGeom_SeamCurve; + aFirstSeamCurve->Init(new TCollection_HAsciiString, + aLine1, + new StepGeom_HArray1OfPcurveOrSurface, + StepGeom_pscrCurve3d); + addToModel(aFirstSeamCurve); + + // Creating SeamCurve containing the second Line. + Handle(StepGeom_SeamCurve) aSecondSeamCurve = new StepGeom_SeamCurve; + aSecondSeamCurve->Init(new TCollection_HAsciiString, + aLine2, + new StepGeom_HArray1OfPcurveOrSurface, + StepGeom_pscrCurve3d); + addToModel(aSecondSeamCurve); + + // Performing removal of duplicate Lines. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateLines(); + + // Check that one Line was removed. + EXPECT_EQ(aRemovedEntities.Size(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(aLine1) || aRemovedEntities.Contains(aLine2)); +} diff --git a/src/DataExchange/TKDESTEP/GTests/StepTidy_Merger_Test.cxx b/src/DataExchange/TKDESTEP/GTests/StepTidy_Merger_Test.cxx new file mode 100644 index 0000000000..5dc9193be5 --- /dev/null +++ b/src/DataExchange/TKDESTEP/GTests/StepTidy_Merger_Test.cxx @@ -0,0 +1,113 @@ +// 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 "StepTidy_BaseTestFixture.pxx" + +#include + +#include + +class StepTidy_DuplicateCleanerTest : public StepTidy_BaseTestFixture +{ +protected: + // Get the number of entities of the specified type. + // @param theType the type of entities to count. + // @return the number of entities of the specified type. + int getEntitiesCount(const Handle(Standard_Type)& theType) const + { + int aCount = 0; + for (Standard_Integer i = 1; i <= myWS->Model()->NbEntities(); i++) + { + if (myWS->Model()->Value(i)->IsKind(theType)) + { + aCount++; + } + } + return aCount; + } + + //! Perform removal of duplicate entities points. + void performRemoval() + { + StepTidy_DuplicateCleaner aMerger(myWS); + aMerger.Perform(); + } +}; + +// Check that entities with the same coordinates and different names are not merged. +TEST_F(StepTidy_DuplicateCleanerTest, DifferentEntities) +{ + // Creating directions. + Handle(StepGeom_Direction) aDir1 = addDirection("dir1"); + Handle(StepGeom_Direction) aDir2 = addDirection("dir2"); + + // Creating vector containing the first direction. + Handle(StepGeom_Vector) aFirstVector = new StepGeom_Vector; + aFirstVector->Init(new TCollection_HAsciiString, aDir1, 1.); + addToModel(aFirstVector); + + // Creating vector containing the second direction. + Handle(StepGeom_Vector) aSecondVector = new StepGeom_Vector; + aSecondVector->Init(new TCollection_HAsciiString, aDir2, 1.); + addToModel(aSecondVector); + + const int aDirectionCountBefore = getEntitiesCount(STANDARD_TYPE(StepGeom_Direction)); + + // Performing removal of duplicate directions. + performRemoval(); + + const int aDirectionCountAfter = getEntitiesCount(STANDARD_TYPE(StepGeom_Direction)); + + // Check that nothing was removed. + EXPECT_EQ(aDirectionCountBefore, 2); + EXPECT_EQ(aDirectionCountBefore, aDirectionCountAfter); +} + +// Check that entities with the same coordinates and same names are +// merged for StepGeom_Axis1Placement. +TEST_F(StepTidy_DuplicateCleanerTest, EqualEntities) +{ + // Creating directions. + Handle(StepGeom_Direction) aDir1 = addDirection(); + Handle(StepGeom_Direction) aDir2 = addDirection(); + + // Creating Cartesian point for the location. + Handle(StepGeom_CartesianPoint) aLocation = new StepGeom_CartesianPoint; + Handle(TColStd_HArray1OfReal) aLocationCoords = new TColStd_HArray1OfReal(1, 3); + aLocationCoords->SetValue(1, 0.); + aLocationCoords->SetValue(2, 0.); + aLocationCoords->SetValue(3, 0.); + aLocation->Init(new TCollection_HAsciiString, aLocationCoords); + addToModel(aLocation); + + // Creating axis containing the first direction. + Handle(StepGeom_Axis1Placement) aFirstAxis = new StepGeom_Axis1Placement; + aFirstAxis->Init(new TCollection_HAsciiString, aLocation, true, aDir1); + addToModel(aFirstAxis); + + // Creating axis containing the second direction. + Handle(StepGeom_Axis1Placement) aSecondAxis = new StepGeom_Axis1Placement; + aSecondAxis->Init(new TCollection_HAsciiString, aLocation, true, aDir2); + addToModel(aSecondAxis); + + const int aDirectionCountBefore = getEntitiesCount(STANDARD_TYPE(StepGeom_Direction)); + + // Performing removal of duplicate directions. + performRemoval(); + + const int aDirectionCountAfter = getEntitiesCount(STANDARD_TYPE(StepGeom_Direction)); + + // Check that one direction was removed. + EXPECT_EQ(aDirectionCountBefore, 2); + EXPECT_EQ(aDirectionCountAfter, 1); +} diff --git a/src/DataExchange/TKDESTEP/GTests/StepTidy_PlaneReducer_Test.cxx b/src/DataExchange/TKDESTEP/GTests/StepTidy_PlaneReducer_Test.cxx new file mode 100644 index 0000000000..bc6e95ee20 --- /dev/null +++ b/src/DataExchange/TKDESTEP/GTests/StepTidy_PlaneReducer_Test.cxx @@ -0,0 +1,128 @@ +// 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 "StepTidy_BaseTestFixture.pxx" + +#include + +#include +#include +#include + +class StepTidy_PlaneReducerTest : public StepTidy_BaseTestFixture +{ +protected: + //! Perform removal of duplicate entities. + TColStd_MapOfTransient replaceDuplicatePlanes() + { + StepTidy_PlaneReducer aReducer(myWS); + for (Standard_Integer anIndex = 1; anIndex <= myWS->Model()->NbEntities(); ++anIndex) + { + aReducer.ProcessEntity(myWS->Model()->Value(anIndex)); + } + + TColStd_MapOfTransient aRemovedEntities; + aReducer.Perform(aRemovedEntities); + return aRemovedEntities; + } +}; + +// Check that Planes with different names are not merged. +TEST_F(StepTidy_PlaneReducerTest, DifferentNames) +{ + // Creating Planes. + Handle(StepGeom_Plane) aPlane1 = addPlane("Plane1"); + Handle(StepGeom_Plane) aPlane2 = addPlane("Plane2"); + + // Creating StepShape_AdvancedFace containing the first Plane. + Handle(StepShape_AdvancedFace) aFirstAdvancedFace = new StepShape_AdvancedFace; + aFirstAdvancedFace->Init(new TCollection_HAsciiString, + new StepShape_HArray1OfFaceBound, + aPlane1, + Standard_True); + addToModel(aFirstAdvancedFace); + + // Creating StepShape_AdvancedFace containing the second Plane. + Handle(StepShape_AdvancedFace) aSecondAdvancedFace = new StepShape_AdvancedFace; + aSecondAdvancedFace->Init(new TCollection_HAsciiString, + new StepShape_HArray1OfFaceBound, + aPlane2, + Standard_True); + addToModel(aSecondAdvancedFace); + + // Performing removal of duplicate Planes. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicatePlanes(); + + // Check that nothing was removed. + EXPECT_TRUE(aRemovedEntities.IsEmpty()); +} + +// Check that equal Planes are merged for StepShape_AdvancedFace. +TEST_F(StepTidy_PlaneReducerTest, StepShape_AdvancedFace) +{ + // Creating Planes. + Handle(StepGeom_Plane) aPlane1 = addPlane(); + Handle(StepGeom_Plane) aPlane2 = addPlane(); + + // Creating StepShape_AdvancedFace containing the first Plane. + Handle(StepShape_AdvancedFace) aFirstAdvancedFace = new StepShape_AdvancedFace; + aFirstAdvancedFace->Init(new TCollection_HAsciiString, + new StepShape_HArray1OfFaceBound, + aPlane1, + Standard_True); + addToModel(aFirstAdvancedFace); + + // Creating StepShape_AdvancedFace containing the second Plane. + Handle(StepShape_AdvancedFace) aSecondAdvancedFace = new StepShape_AdvancedFace; + aSecondAdvancedFace->Init(new TCollection_HAsciiString, + new StepShape_HArray1OfFaceBound, + aPlane2, + Standard_True); + addToModel(aSecondAdvancedFace); + + // Performing removal of duplicate Planes. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicatePlanes(); + + // Check that one Plane was removed. + EXPECT_EQ(aRemovedEntities.Size(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(aPlane1) || aRemovedEntities.Contains(aPlane2)); +} + +// Check that equal Planes are merged for StepGeom_Pcurve. +TEST_F(StepTidy_PlaneReducerTest, StepGeom_Pcurve) +{ + // Creating Planes. + Handle(StepGeom_Plane) aPlane1 = addPlane(); + Handle(StepGeom_Plane) aPlane2 = addPlane(); + + // Creating StepGeom_Pcurve containing the first Plane. + Handle(StepGeom_Pcurve) aFirstPcurve = new StepGeom_Pcurve; + aFirstPcurve->Init(new TCollection_HAsciiString, + aPlane1, + new StepRepr_DefinitionalRepresentation); + addToModel(aFirstPcurve); + + // Creating StepGeom_Pcurve containing the second Plane. + Handle(StepGeom_Pcurve) aSecondPcurve = new StepGeom_Pcurve; + aSecondPcurve->Init(new TCollection_HAsciiString, + aPlane2, + new StepRepr_DefinitionalRepresentation); + addToModel(aSecondPcurve); + + // Performing removal of duplicate Planes. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicatePlanes(); + + // Check that one Plane was removed. + EXPECT_EQ(aRemovedEntities.Size(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(aPlane1) || aRemovedEntities.Contains(aPlane2)); +} diff --git a/src/DataExchange/TKDESTEP/GTests/StepTidy_VectorReducer_Test.cxx b/src/DataExchange/TKDESTEP/GTests/StepTidy_VectorReducer_Test.cxx new file mode 100644 index 0000000000..f6a44e33bc --- /dev/null +++ b/src/DataExchange/TKDESTEP/GTests/StepTidy_VectorReducer_Test.cxx @@ -0,0 +1,92 @@ +// 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 "StepTidy_BaseTestFixture.pxx" + +#include + +#include + +class StepTidy_VectorReducerTest : public StepTidy_BaseTestFixture +{ +protected: + //! Perform removal of duplicate entities. + TColStd_MapOfTransient replaceDuplicateVectors() + { + StepTidy_VectorReducer aReducer(myWS); + for (Standard_Integer anIndex = 1; anIndex <= myWS->Model()->NbEntities(); ++anIndex) + { + aReducer.ProcessEntity(myWS->Model()->Value(anIndex)); + } + + TColStd_MapOfTransient aRemovedEntities; + aReducer.Perform(aRemovedEntities); + return aRemovedEntities; + } +}; + +// Check that Vectors with the same coordinates and different names are not merged. +TEST_F(StepTidy_VectorReducerTest, DifferentNames) +{ + // Creating Vectors. + Handle(StepGeom_Vector) aVec1 = addVector("vec1"); + Handle(StepGeom_Vector) aVec2 = addVector("vec2"); + + // Creating a cartesian point for the lines. + Handle(StepGeom_CartesianPoint) aPnt = addCartesianPoint(nullptr, {0., 0., 0.}); + + // Creating aLine containing the first Vector. + Handle(StepGeom_Line) aLine1 = new StepGeom_Line; + aLine1->Init(new TCollection_HAsciiString, aPnt, aVec1); + addToModel(aLine1); + + // Creating aLine containing the second Vector. + Handle(StepGeom_Line) aLine2 = new StepGeom_Line; + aLine2->Init(new TCollection_HAsciiString, aPnt, aVec2); + addToModel(aLine2); + + // Performing removal of duplicate Vectors. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateVectors(); + + // Check that nothing was removed. + EXPECT_TRUE(aRemovedEntities.IsEmpty()); +} + +// Check that Vectors with the same coordinates and same names are +// merged for StepGeom_Axis1Placement. +TEST_F(StepTidy_VectorReducerTest, StepGeom_Line) +{ + // Creating Vectors. + Handle(StepGeom_Vector) aVec1 = addVector(); + Handle(StepGeom_Vector) aVec2 = addVector(); + + // Creating a cartesian point for the lines. + Handle(StepGeom_CartesianPoint) aPnt = addCartesianPoint(nullptr, {0., 0., 0.}); + + // Creating aLine containing the first Vector. + Handle(StepGeom_Line) aLine1 = new StepGeom_Line; + aLine1->Init(new TCollection_HAsciiString, aPnt, aVec1); + addToModel(aLine1); + + // Creating aLine containing the second Vector. + Handle(StepGeom_Line) aLine2 = new StepGeom_Line; + aLine2->Init(new TCollection_HAsciiString, aPnt, aVec2); + addToModel(aLine2); + + // Performing removal of duplicate Vectors. + TColStd_MapOfTransient aRemovedEntities = replaceDuplicateVectors(); + + // Check that duplicate was removed. + EXPECT_EQ(aRemovedEntities.Size(), 1); + EXPECT_TRUE(aRemovedEntities.Contains(aVec1) || aRemovedEntities.Contains(aVec2)); +} diff --git a/src/DataExchange/TKDESTEP/MergeSTEPEntities/FILES.cmake b/src/DataExchange/TKDESTEP/MergeSTEPEntities/FILES.cmake deleted file mode 100644 index c55d38ebbd..0000000000 --- a/src/DataExchange/TKDESTEP/MergeSTEPEntities/FILES.cmake +++ /dev/null @@ -1,30 +0,0 @@ -# Source files for STEPControl package -set(OCCT_MergeSTEPEntities_FILES_LOCATION "${CMAKE_CURRENT_LIST_DIR}") - -set(OCCT_MergeSTEPEntities_FILES - MergeSTEPEntities_Axis2Placement2dHasher.hxx - MergeSTEPEntities_Axis2Placement3dHasher.hxx - MergeSTEPEntities_Axis2Placement3dProcessor.cxx - MergeSTEPEntities_Axis2Placement3dProcessor.hxx - MergeSTEPEntities_CartesianPointHasher.hxx - MergeSTEPEntities_CartesianPointProcessor.cxx - MergeSTEPEntities_CartesianPointProcessor.hxx - MergeSTEPEntities_CircleHasher.hxx - MergeSTEPEntities_CircleProcessor.cxx - MergeSTEPEntities_CircleProcessor.hxx - MergeSTEPEntities_DirectionHasher.hxx - MergeSTEPEntities_DirectionProcessor.cxx - MergeSTEPEntities_DirectionProcessor.hxx - MergeSTEPEntities_EntityProcessor.hxx - MergeSTEPEntities_LineHasher.hxx - MergeSTEPEntities_LineProcessor.cxx - MergeSTEPEntities_LineProcessor.hxx - MergeSTEPEntities_Merger.cxx - MergeSTEPEntities_Merger.hxx - MergeSTEPEntities_PlaneHasher.hxx - MergeSTEPEntities_PlaneProcessor.cxx - MergeSTEPEntities_PlaneProcessor.hxx - MergeSTEPEntities_VectorHasher.hxx - MergeSTEPEntities_VectorProcessor.cxx - MergeSTEPEntities_VectorProcessor.hxx -) diff --git a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_Axis2Placement2dHasher.hxx b/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_Axis2Placement2dHasher.hxx deleted file mode 100644 index a98f3bfe0c..0000000000 --- a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_Axis2Placement2dHasher.hxx +++ /dev/null @@ -1,80 +0,0 @@ -// 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. - -#ifndef _MergeSTEPEntities_Axis2Placement2dHasher_HeaderFile -#define _MergeSTEPEntities_Axis2Placement2dHasher_HeaderFile - -#include -#include - -#include -#include - -//! OCCT-style hasher for StepGeom_Axis2Placement2d entities. -//! Currently only used for implementation of hasher for StepGeom_Circle. -struct MergeSTEPEntities_Axis2Placement2dHasher -{ - // Hashes the axis placements. - std::size_t operator()(const Handle(StepGeom_Axis2Placement2d)& thePlacement) const noexcept - { - // Prepare an array of hashes for the location, axis, and ref direction. - // Optimal seed is used for the axis and ref direction if they are not present. - const size_t aHashes[2]{MergeSTEPEntities_CartesianPointHasher{}(thePlacement->Location()), - thePlacement->HasRefDirection() - ? MergeSTEPEntities_DirectionHasher{}(thePlacement->RefDirection()) - : opencascade::MurmurHash::optimalSeed()}; - const size_t aHash = opencascade::hashBytes(aHashes, sizeof(aHashes)); - if (thePlacement->Name().IsNull()) - { - // If the name is not present, return the hash. - return aHash; - } - // Add the name to the hash if it is present. - const size_t aHashWithName[2]{ - aHash, - std::hash{}(thePlacement->Name()->String())}; - return opencascade::hashBytes(aHashWithName, sizeof(aHashWithName)); - } - - // Compares two axis placements. - bool operator()(const Handle(StepGeom_Axis2Placement2d)& thePlacement1, - const Handle(StepGeom_Axis2Placement2d)& thePlacement2) const noexcept - { - // Compare names. - if (thePlacement1->Name().IsNull() != thePlacement2->Name().IsNull()) - { - return false; - } - if (!thePlacement1->Name()->IsSameString(thePlacement2->Name())) - { - return false; - } - - // Compare location, axis, and ref direction. - const bool isSameLocation = MergeSTEPEntities_CartesianPointHasher{}(thePlacement1->Location(), - thePlacement2->Location()); - // Have to check if the axis is present and compare it. - // Have to check if the ref direction is present and compare it. - const bool isSameRefDirectionFlag = - thePlacement1->HasRefDirection() == thePlacement2->HasRefDirection(); - const bool isSameRefDirection = - isSameRefDirectionFlag - && (!thePlacement1->HasRefDirection() - || MergeSTEPEntities_DirectionHasher{}(thePlacement1->RefDirection(), - thePlacement2->RefDirection())); - - return isSameLocation && isSameRefDirection; - } -}; - -#endif // _MergeSTEPEntities_Axis2Placement2dHasher_HeaderFile diff --git a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_Axis2Placement3dHasher.hxx b/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_Axis2Placement3dHasher.hxx deleted file mode 100644 index 9d0c70d14f..0000000000 --- a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_Axis2Placement3dHasher.hxx +++ /dev/null @@ -1,87 +0,0 @@ -// 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. - -#ifndef _MergeSTEPEntities_Axis2Placement3dHasher_HeaderFile -#define _MergeSTEPEntities_Axis2Placement3dHasher_HeaderFile - -#include -#include - -#include -#include - -//! OCCT-style hasher for StepGeom_Axis2Placement3d entities. -struct MergeSTEPEntities_Axis2Placement3dHasher -{ - // Hashes the axis placements. - std::size_t operator()(const Handle(StepGeom_Axis2Placement3d)& thePlacement) const noexcept - { - // Prepare an array of hashes for the location, axis, and ref direction. - // Optimal seed is used for the axis and ref direction if they are not present. - const size_t aHashes[3]{MergeSTEPEntities_CartesianPointHasher{}(thePlacement->Location()), - thePlacement->HasAxis() - ? MergeSTEPEntities_DirectionHasher{}(thePlacement->Axis()) - : opencascade::MurmurHash::optimalSeed(), - thePlacement->HasRefDirection() - ? MergeSTEPEntities_DirectionHasher{}(thePlacement->RefDirection()) - : opencascade::MurmurHash::optimalSeed()}; - const size_t aHash = opencascade::hashBytes(aHashes, sizeof(aHashes)); - if (thePlacement->Name().IsNull()) - { - // If the name is not present, return the hash. - return aHash; - } - // Add the name to the hash if it is present. - const size_t aHashWithName[2]{ - aHash, - std::hash{}(thePlacement->Name()->String())}; - return opencascade::hashBytes(aHashWithName, sizeof(aHashWithName)); - } - - // Compares two axis placements. - bool operator()(const Handle(StepGeom_Axis2Placement3d)& thePlacement1, - const Handle(StepGeom_Axis2Placement3d)& thePlacement2) const noexcept - { - // Compare names. - if (thePlacement1->Name().IsNull() != thePlacement2->Name().IsNull()) - { - return false; - } - if (!thePlacement1->Name()->IsSameString(thePlacement2->Name())) - { - return false; - } - - // Compare location, axis, and ref direction. - const bool isSameLocation = MergeSTEPEntities_CartesianPointHasher{}(thePlacement1->Location(), - thePlacement2->Location()); - // Have to check if the axis is present and compare it. - const bool isSameAxisFlag = thePlacement1->HasAxis() == thePlacement2->HasAxis(); - const bool isSameAxis = - isSameAxisFlag - && (!thePlacement1->HasAxis() - || MergeSTEPEntities_DirectionHasher{}(thePlacement1->Axis(), thePlacement2->Axis())); - // Have to check if the ref direction is present and compare it. - const bool isSameRefDirectionFlag = - thePlacement1->HasRefDirection() == thePlacement2->HasRefDirection(); - const bool isSameRefDirection = - isSameRefDirectionFlag - && (!thePlacement1->HasRefDirection() - || MergeSTEPEntities_DirectionHasher{}(thePlacement1->RefDirection(), - thePlacement2->RefDirection())); - - return isSameLocation && isSameAxis && isSameRefDirection; - } -}; - -#endif // _MergeSTEPEntities_Axis2Placement3dHasher_HeaderFile diff --git a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_Axis2Placement3dProcessor.cxx b/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_Axis2Placement3dProcessor.cxx deleted file mode 100644 index b1e49a4bdc..0000000000 --- a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_Axis2Placement3dProcessor.cxx +++ /dev/null @@ -1,299 +0,0 @@ -// 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 - -//================================================================================================== - -MergeSTEPEntities_Axis2Placement3dProcessor::MergeSTEPEntities_Axis2Placement3dProcessor( - const Handle(XSControl_WorkSession)& theWS) - : MergeSTEPEntities_EntityProcessor(theWS) -{ - registerReplacer(STANDARD_TYPE(StepGeom_Plane), replacePlane); - registerReplacer(STANDARD_TYPE(StepRepr_ItemDefinedTransformation), - replaceItemDefinedTransformation); - registerReplacer(STANDARD_TYPE(StepGeom_CylindricalSurface), replaceCylindricalSurface); - registerReplacer(STANDARD_TYPE(StepShape_ShapeRepresentation), replaceShapeRepresentation); - registerReplacer(STANDARD_TYPE(StepRepr_ConstructiveGeometryRepresentation), - replaceConstructiveGeometryRepresentation); - registerReplacer(STANDARD_TYPE(StepGeom_Circle), replaceCircle); - registerReplacer(STANDARD_TYPE(StepVisual_PresentationLayerAssignment), - replacePresentationLayerAssignment); - registerReplacer(STANDARD_TYPE(StepVisual_StyledItem), replaceStyledItem); - registerReplacer(STANDARD_TYPE(StepGeom_Ellipse), replaceEllipse); - registerReplacer(STANDARD_TYPE(StepGeom_ConicalSurface), replaceConicalSurface); - registerReplacer(STANDARD_TYPE(StepGeom_ToroidalSurface), replaceToroidalSurface); - registerReplacer(STANDARD_TYPE(StepShape_AdvancedBrepShapeRepresentation), - replaceAdvancedBrepShapeRepresentation); - registerReplacer(STANDARD_TYPE(StepGeom_SphericalSurface), replaceSphericalSurface); -} - -//================================================================================================== - -bool MergeSTEPEntities_Axis2Placement3dProcessor::replacePlane( - const Handle(StepGeom_Axis2Placement3d)& theOldEntity, - const Handle(StepGeom_Axis2Placement3d)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepGeom_Plane) aSharing = Handle(StepGeom_Plane)::DownCast(theSharing); - if (aSharing->Position() == theOldEntity) - { - aSharing->SetPosition(theNewEntity); - return true; - } - return false; -} - -//================================================================================================== - -bool MergeSTEPEntities_Axis2Placement3dProcessor::replaceItemDefinedTransformation( - const Handle(StepGeom_Axis2Placement3d)& theOldEntity, - const Handle(StepGeom_Axis2Placement3d)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepRepr_ItemDefinedTransformation) aSharing = - Handle(StepRepr_ItemDefinedTransformation)::DownCast(theSharing); - bool isReplaced = false; - if (aSharing->TransformItem1() == theOldEntity) - { - aSharing->SetTransformItem1(theNewEntity); - isReplaced = true; - } - if (aSharing->TransformItem2() == theOldEntity) - { - aSharing->SetTransformItem2(theNewEntity); - isReplaced = true; - } - return isReplaced; -} - -//================================================================================================== - -bool MergeSTEPEntities_Axis2Placement3dProcessor::replaceCylindricalSurface( - const Handle(StepGeom_Axis2Placement3d)& theOldEntity, - const Handle(StepGeom_Axis2Placement3d)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepGeom_CylindricalSurface) aSharing = - Handle(StepGeom_CylindricalSurface)::DownCast(theSharing); - if (aSharing->Position() == theOldEntity) - { - aSharing->SetPosition(theNewEntity); - return true; - } - return false; -} - -//================================================================================================== - -bool MergeSTEPEntities_Axis2Placement3dProcessor::replaceShapeRepresentation( - const Handle(StepGeom_Axis2Placement3d)& theOldEntity, - const Handle(StepGeom_Axis2Placement3d)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepShape_ShapeRepresentation) aSharing = - Handle(StepShape_ShapeRepresentation)::DownCast(theSharing); - bool isReplaced = false; - for (Standard_Integer anIndex = aSharing->Items()->Lower(); anIndex <= aSharing->Items()->Upper(); - ++anIndex) - { - if (aSharing->Items()->Value(anIndex) == theOldEntity) - { - aSharing->Items()->SetValue(anIndex, theNewEntity); - isReplaced = true; - } - } - return isReplaced; -} - -//================================================================================================== - -bool MergeSTEPEntities_Axis2Placement3dProcessor::replaceConstructiveGeometryRepresentation( - const Handle(StepGeom_Axis2Placement3d)& theOldEntity, - const Handle(StepGeom_Axis2Placement3d)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepRepr_ConstructiveGeometryRepresentation) aSharing = - Handle(StepRepr_ConstructiveGeometryRepresentation)::DownCast(theSharing); - bool isReplaced = false; - for (Standard_Integer anIndex = aSharing->Items()->Lower(); anIndex <= aSharing->Items()->Upper(); - ++anIndex) - { - if (aSharing->Items()->Value(anIndex) == theOldEntity) - { - aSharing->Items()->SetValue(anIndex, theNewEntity); - isReplaced = true; - } - } - return isReplaced; -} - -//================================================================================================== - -bool MergeSTEPEntities_Axis2Placement3dProcessor::replaceCircle( - const Handle(StepGeom_Axis2Placement3d)& theOldEntity, - const Handle(StepGeom_Axis2Placement3d)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepGeom_Circle) aSharing = Handle(StepGeom_Circle)::DownCast(theSharing); - StepGeom_Axis2Placement aSelector = aSharing->Position(); - if (aSelector.Axis2Placement3d() == theOldEntity) - { - aSelector.SetValue(theNewEntity); - return true; - } - return false; -} - -//================================================================================================== - -bool MergeSTEPEntities_Axis2Placement3dProcessor::replacePresentationLayerAssignment( - const Handle(StepGeom_Axis2Placement3d)& theOldEntity, - const Handle(StepGeom_Axis2Placement3d)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepVisual_PresentationLayerAssignment) aSharing = - Handle(StepVisual_PresentationLayerAssignment)::DownCast(theSharing); - bool isReplaced = false; - Handle(StepVisual_HArray1OfLayeredItem) anItems = aSharing->AssignedItems(); - for (Standard_Integer anIndex = anItems->Lower(); anIndex <= anItems->Upper(); ++anIndex) - { - StepVisual_LayeredItem& aLayeredItem = anItems->ChangeValue(anIndex); - if (aLayeredItem.RepresentationItem() == theOldEntity) - { - aLayeredItem.SetValue(theNewEntity); - isReplaced = true; - } - } - return isReplaced; -} - -//================================================================================================== - -bool MergeSTEPEntities_Axis2Placement3dProcessor::replaceStyledItem( - const Handle(StepGeom_Axis2Placement3d)& theOldEntity, - const Handle(StepGeom_Axis2Placement3d)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepVisual_StyledItem) aSharing = Handle(StepVisual_StyledItem)::DownCast(theSharing); - if (aSharing->Item() == theOldEntity) - { - aSharing->SetItem(theNewEntity); - return true; - } - return false; -} - -//================================================================================================== - -bool MergeSTEPEntities_Axis2Placement3dProcessor::replaceEllipse( - const Handle(StepGeom_Axis2Placement3d)& theOldEntity, - const Handle(StepGeom_Axis2Placement3d)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepGeom_Ellipse) aSharing = Handle(StepGeom_Ellipse)::DownCast(theSharing); - StepGeom_Axis2Placement aSelector = aSharing->Position(); - if (aSelector.Axis2Placement3d() == theOldEntity) - { - aSelector.SetValue(theNewEntity); - return true; - } - return false; -} - -//================================================================================================== - -bool MergeSTEPEntities_Axis2Placement3dProcessor::replaceConicalSurface( - const Handle(StepGeom_Axis2Placement3d)& theOldEntity, - const Handle(StepGeom_Axis2Placement3d)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepGeom_ConicalSurface) aSharing = Handle(StepGeom_ConicalSurface)::DownCast(theSharing); - if (aSharing->Position() == theOldEntity) - { - aSharing->SetPosition(theNewEntity); - return true; - } - return false; -} - -//================================================================================================== - -bool MergeSTEPEntities_Axis2Placement3dProcessor::replaceToroidalSurface( - const Handle(StepGeom_Axis2Placement3d)& theOldEntity, - const Handle(StepGeom_Axis2Placement3d)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepGeom_ToroidalSurface) aSharing = - Handle(StepGeom_ToroidalSurface)::DownCast(theSharing); - if (aSharing->Position() == theOldEntity) - { - aSharing->SetPosition(theNewEntity); - return true; - } - return false; -} - -//================================================================================================== - -bool MergeSTEPEntities_Axis2Placement3dProcessor::replaceAdvancedBrepShapeRepresentation( - const Handle(StepGeom_Axis2Placement3d)& theOldEntity, - const Handle(StepGeom_Axis2Placement3d)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepShape_AdvancedBrepShapeRepresentation) aSharing = - Handle(StepShape_AdvancedBrepShapeRepresentation)::DownCast(theSharing); - bool isReplaced = false; - for (Standard_Integer anIndex = aSharing->Items()->Lower(); anIndex <= aSharing->Items()->Upper(); - ++anIndex) - { - if (aSharing->Items()->Value(anIndex) == theOldEntity) - { - aSharing->Items()->SetValue(anIndex, theNewEntity); - isReplaced = true; - } - } - return isReplaced; -} - -//================================================================================================== - -bool MergeSTEPEntities_Axis2Placement3dProcessor::replaceSphericalSurface( - const Handle(StepGeom_Axis2Placement3d)& theOldEntity, - const Handle(StepGeom_Axis2Placement3d)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepGeom_SphericalSurface) aSharing = - Handle(StepGeom_SphericalSurface)::DownCast(theSharing); - if (aSharing->Position() == theOldEntity) - { - aSharing->SetPosition(theNewEntity); - return true; - } - return false; -} diff --git a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_Axis2Placement3dProcessor.hxx b/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_Axis2Placement3dProcessor.hxx deleted file mode 100644 index c46247c8d4..0000000000 --- a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_Axis2Placement3dProcessor.hxx +++ /dev/null @@ -1,160 +0,0 @@ -// 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. - -#ifndef _MergeSTEPEntities_Axis2Placement3dProcessor_HeaderFile -#define _MergeSTEPEntities_Axis2Placement3dProcessor_HeaderFile - -#include -#include - -#include - -//! Processor for merging StepGeom_Axis2Placement3d entities. -//! This processor merges axis placements with the same location, axis, and ref direction. -class MergeSTEPEntities_Axis2Placement3dProcessor - : public MergeSTEPEntities_EntityProcessor -{ -public: - //! Constructor. Stores the work session and registers replacer functions. - //! @param theWS the work session. - Standard_EXPORT MergeSTEPEntities_Axis2Placement3dProcessor( - const Handle(XSControl_WorkSession)& theWS); - -private: - //! Replaces the old axis placement with the new one in the StepGeom_Plane entity. - //! @param theOldEntity the old axis placement. - //! @param theNewEntity the new axis placement to replace the old one. - //! @param theSharing the StepGeom_Plane entity to update. - //! @return true if the axis placement was replaced, false otherwise. - static bool replacePlane(const Handle(StepGeom_Axis2Placement3d)& theOldEntity, - const Handle(StepGeom_Axis2Placement3d)& theNewEntity, - Handle(Standard_Transient) theSharing); - - //! Replaces the old axis placement with the new one in the StepRepr_ItemDefinedTransformation - //! entity. - //! @param theOldEntity the old axis placement. - //! @param theNewEntity the new axis placement to replace the old one. - //! @param theSharing the StepRepr_ItemDefinedTransformation entity to update. - //! @return true if the axis placement was replaced, false otherwise. - static bool replaceItemDefinedTransformation( - const Handle(StepGeom_Axis2Placement3d)& theOldEntity, - const Handle(StepGeom_Axis2Placement3d)& theNewEntity, - Handle(Standard_Transient) theSharing); - - //! Replaces the old axis placement with the new one in the StepGeom_CylindricalSurface entity. - //! @param theOldEntity the old axis placement. - //! @param theNewEntity the new axis placement to replace the old one. - //! @param theSharing the StepGeom_CylindricalSurface entity to update. - //! @return true if the axis placement was replaced, false otherwise. - static bool replaceCylindricalSurface(const Handle(StepGeom_Axis2Placement3d)& theOldEntity, - const Handle(StepGeom_Axis2Placement3d)& theNewEntity, - Handle(Standard_Transient) theSharing); - - //! Replaces the old axis placement with the new one in the StepShape_ShapeRepresentation entity. - //! @param theOldEntity the old axis placement. - //! @param theNewEntity the new axis placement to replace the old one. - //! @param theSharing the StepShape_ShapeRepresentation entity to update. - //! @return true if the axis placement was replaced, false otherwise. - static bool replaceShapeRepresentation(const Handle(StepGeom_Axis2Placement3d)& theOldEntity, - const Handle(StepGeom_Axis2Placement3d)& theNewEntity, - Handle(Standard_Transient) theSharing); - - //! Replaces the old axis placement with the new one in the - //! StepRepr_ConstructiveGeometryRepresentation entity. - //! @param theOldEntity the old axis placement. - //! @param theNewEntity the new axis placement to replace the old one. - //! @param theSharing the StepRepr_ConstructiveGeometryRepresentation entity to update. - //! @return true if the axis placement was replaced, false otherwise. - static bool replaceConstructiveGeometryRepresentation( - const Handle(StepGeom_Axis2Placement3d)& theOldEntity, - const Handle(StepGeom_Axis2Placement3d)& theNewEntity, - Handle(Standard_Transient) theSharing); - - //! Replaces the old axis placement with the new one in the StepGeom_Circle entity. - //! @param theOldEntity the old axis placement. - //! @param theNewEntity the new axis placement to replace the old one. - //! @param theSharing the StepGeom_Circle entity to update. - //! @return true if the axis placement was replaced, false otherwise. - static bool replaceCircle(const Handle(StepGeom_Axis2Placement3d)& theOldEntity, - const Handle(StepGeom_Axis2Placement3d)& theNewEntity, - Handle(Standard_Transient) theSharing); - - //! Replaces the old axis placement with the new one in the StepGeom_PresentationLayerAssignment - //! @param theOldEntity the old axis placement. - //! @param theNewEntity the new axis placement to replace the old one. - //! @param theSharing the StepGeom_PresentationLayerAssignment entity to update. - //! @return true if the axis placement was replaced, false otherwise. - static bool replacePresentationLayerAssignment( - const Handle(StepGeom_Axis2Placement3d)& theOldEntity, - const Handle(StepGeom_Axis2Placement3d)& theNewEntity, - Handle(Standard_Transient) theSharing); - - //! Replaces the old axis placement with the new one in the StepVisual_StyledItem entity. - //! @param theOldEntity the old axis placement. - //! @param theNewEntity the new axis placement to replace the old one. - //! @param theSharing the StepVisual_StyledItem entity to update. - //! @return true if the axis placement was replaced, false otherwise. - static bool replaceStyledItem(const Handle(StepGeom_Axis2Placement3d)& theOldEntity, - const Handle(StepGeom_Axis2Placement3d)& theNewEntity, - Handle(Standard_Transient) theSharing); - - //! Replaces the old axis placement with the new one in the StepGeom_Ellipse entity. - //! @param theOldEntity the old axis placement. - //! @param theNewEntity the new axis placement to replace the old one. - //! @param theSharing the StepGeom_Ellipse entity to update. - //! @return true if the axis placement was replaced, false otherwise. - static bool replaceEllipse(const Handle(StepGeom_Axis2Placement3d)& theOldEntity, - const Handle(StepGeom_Axis2Placement3d)& theNewEntity, - Handle(Standard_Transient) theSharing); - - //! Replaces the old axis placement with the new one in the StepGeom_ConicalSurface entity. - //! @param theOldEntity the old axis placement. - //! @param theNewEntity the new axis placement to replace the old one. - //! @param theSharing the StepGeom_ConicalSurface entity to update. - //! @return true if the axis placement was replaced, false otherwise. - static bool replaceConicalSurface(const Handle(StepGeom_Axis2Placement3d)& theOldEntity, - const Handle(StepGeom_Axis2Placement3d)& theNewEntity, - Handle(Standard_Transient) theSharing); - - //! Replaces the old axis placement with the new one in the StepGeom_ToroidalSurface entity. - //! @param theOldEntity the old axis placement. - //! @param theNewEntity the new axis placement to replace the old one. - //! @param theSharing the StepGeom_ToroidalSurface entity to update. - //! @return true if the axis placement was replaced, false otherwise. - static bool replaceToroidalSurface(const Handle(StepGeom_Axis2Placement3d)& theOldEntity, - const Handle(StepGeom_Axis2Placement3d)& theNewEntity, - Handle(Standard_Transient) theSharing); - - //! Replaces the old axis placement with the new one in the - //! StepShape_AdvancedBrepShapeRepresentation entity. - //! @param theOldEntity the old axis placement. - //! @param theNewEntity the new axis placement to replace the old one. - //! @param theSharing the StepShape_AdvancedBrepShapeRepresentation entity to update. - //! @return true if the axis placement was replaced, false otherwise. - static bool replaceAdvancedBrepShapeRepresentation( - const Handle(StepGeom_Axis2Placement3d)& theOldEntity, - const Handle(StepGeom_Axis2Placement3d)& theNewEntity, - Handle(Standard_Transient) theSharing); - - //! Replaces the old axis placement with the new one in the StepGeom_SphericalSurface entity. - //! @param theOldEntity the old axis placement. - //! @param theNewEntity the new axis placement to replace the old one. - //! @param theSharing the StepGeom_SphericalSurface entity to update. - //! @return true if the axis placement was replaced, false otherwise. - static bool replaceSphericalSurface(const Handle(StepGeom_Axis2Placement3d)& theOldEntity, - const Handle(StepGeom_Axis2Placement3d)& theNewEntity, - Handle(Standard_Transient) theSharing); -}; - -#endif // _MergeSTEPEntities_DirectionProcessor_HeaderFile diff --git a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_CartesianPointHasher.hxx b/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_CartesianPointHasher.hxx deleted file mode 100644 index 1349227b4a..0000000000 --- a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_CartesianPointHasher.hxx +++ /dev/null @@ -1,74 +0,0 @@ -// 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. - -#ifndef _MergeSTEPEntities_CartesianPointHasher_HeaderFile -#define _MergeSTEPEntities_CartesianPointHasher_HeaderFile - -#include -#include -#include - -//! OCCT-style hasher for StepGeom_CartesianPoint entities. -struct MergeSTEPEntities_CartesianPointHasher -{ - // Hashes the Cartesian point by its name and coordinates. - std::size_t operator()(const Handle(StepGeom_CartesianPoint)& theCartesianPoint) const noexcept - { - const std::array& aCoords = theCartesianPoint->Coordinates(); - // If Cartesian point has no name, hash only coordinates. - if (theCartesianPoint->Name().IsNull()) - { - return opencascade::hashBytes(aCoords.data(), static_cast(aCoords.size())); - } - // Otherwise, hash both coordinates and name. - const size_t aHashes[2]{ - opencascade::hashBytes(aCoords.data(), static_cast(aCoords.size())), - std::hash{}(theCartesianPoint->Name()->String())}; - - return opencascade::hashBytes(aHashes, sizeof(aHashes)); - } - - // Compares two Cartesian points by their names and coordinates. - bool operator()(const Handle(StepGeom_CartesianPoint)& theCartesianPoint1, - const Handle(StepGeom_CartesianPoint)& theCartesianPoint2) const noexcept - { - // Compare names. - if (theCartesianPoint1->Name().IsNull() != theCartesianPoint2->Name().IsNull()) - { - return false; - } - if (!theCartesianPoint1->Name()->IsSameString(theCartesianPoint2->Name())) - { - return false; - } - - // Compare coordinates. - constexpr double aTolerance = 1e-12; - const std::array& aCoords1 = theCartesianPoint1->Coordinates(); - const std::array& aCoords2 = theCartesianPoint2->Coordinates(); - if (aCoords1.size() != aCoords2.size()) - { - return false; - } - for (size_t anIndex = 0; anIndex < aCoords1.size(); ++anIndex) - { - if (std::abs(aCoords1[anIndex] - aCoords2[anIndex]) > aTolerance) - { - return false; - } - } - return true; - } -}; - -#endif // _MergeSTEPEntities_CartesianPointHasher_HeaderFile diff --git a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_CartesianPointProcessor.cxx b/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_CartesianPointProcessor.cxx deleted file mode 100644 index 54fc8c6c69..0000000000 --- a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_CartesianPointProcessor.cxx +++ /dev/null @@ -1,303 +0,0 @@ -// 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 - -//================================================================================================== - -MergeSTEPEntities_CartesianPointProcessor::MergeSTEPEntities_CartesianPointProcessor( - const Handle(XSControl_WorkSession)& theWS) - : MergeSTEPEntities_EntityProcessor(theWS) -{ - registerReplacer(STANDARD_TYPE(StepGeom_Axis1Placement), replaceAxis1Placement); - registerReplacer(STANDARD_TYPE(StepGeom_Axis2Placement3d), replaceAxis2Placement3d); - registerReplacer(STANDARD_TYPE(StepShape_VertexPoint), replaceVertexPoint); - registerReplacer(STANDARD_TYPE(StepShape_GeometricCurveSet), replaceGeometricCurveSet); - registerReplacer(STANDARD_TYPE(StepVisual_PresentationLayerAssignment), - replacePresentationLayerAssignment); - registerReplacer(STANDARD_TYPE(StepVisual_StyledItem), replaceStyledItem); - registerReplacer(STANDARD_TYPE(StepGeom_BSplineCurveWithKnots), replaceBSplineCurveWithKnots); - registerReplacer(STANDARD_TYPE(StepGeom_Line), replaceLine); - registerReplacer(STANDARD_TYPE(StepGeom_BSplineSurfaceWithKnots), replaceBSplineSurfaceWithKnots); - registerReplacer(STANDARD_TYPE(StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve), - replaceBSplineCurveWithKnotsAndRationalBSplineCurve); - registerReplacer(STANDARD_TYPE(StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface), - replaceBSplineSurfaceWithKnotsAndRationalBSplineSurface); - registerReplacer(STANDARD_TYPE(StepRepr_Representation), replaceRepresentation); -} - -//================================================================================================== - -bool MergeSTEPEntities_CartesianPointProcessor::replaceAxis2Placement3d( - const Handle(StepGeom_CartesianPoint)& theOldEntity, - const Handle(StepGeom_CartesianPoint)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepGeom_Axis2Placement3d) aSharing = - Handle(StepGeom_Axis2Placement3d)::DownCast(theSharing); - if (aSharing->Location() == theOldEntity) - { - aSharing->SetLocation(theNewEntity); - return true; - } - return false; -} - -//================================================================================================== - -bool MergeSTEPEntities_CartesianPointProcessor::replaceVertexPoint( - const Handle(StepGeom_CartesianPoint)& theOldEntity, - const Handle(StepGeom_CartesianPoint)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepShape_VertexPoint) aSharing = Handle(StepShape_VertexPoint)::DownCast(theSharing); - if (aSharing->VertexGeometry() == theOldEntity) - { - aSharing->SetVertexGeometry(theNewEntity); - return true; - } - return false; -} - -//================================================================================================== - -bool MergeSTEPEntities_CartesianPointProcessor::replaceGeometricCurveSet( - const Handle(StepGeom_CartesianPoint)& theOldEntity, - const Handle(StepGeom_CartesianPoint)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepShape_GeometricSet) aSharing = Handle(StepShape_GeometricSet)::DownCast(theSharing); - bool isReplaced = false; - for (auto& anElement : *aSharing->Elements()) - { - const Handle(StepGeom_Point) aCurrentPoint = anElement.Point(); - if (aCurrentPoint && aCurrentPoint == theOldEntity) - { - anElement.SetValue(theNewEntity); - isReplaced = true; - } - } - return isReplaced; -} - -//================================================================================================== - -bool MergeSTEPEntities_CartesianPointProcessor::replacePresentationLayerAssignment( - const Handle(StepGeom_CartesianPoint)& theOldEntity, - const Handle(StepGeom_CartesianPoint)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepVisual_PresentationLayerAssignment) aSharing = - Handle(StepVisual_PresentationLayerAssignment)::DownCast(theSharing); - bool isReplaced = false; - for (auto& anAssignedItem : *aSharing->AssignedItems()) - { - const Handle(StepRepr_RepresentationItem) aRepItem = anAssignedItem.RepresentationItem(); - if (aRepItem == theOldEntity) - { - anAssignedItem.SetValue(theNewEntity); - isReplaced = true; - } - } - return isReplaced; -} - -//================================================================================================== - -bool MergeSTEPEntities_CartesianPointProcessor::replaceStyledItem( - const Handle(StepGeom_CartesianPoint)& theOldEntity, - const Handle(StepGeom_CartesianPoint)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepVisual_StyledItem) aSharing = Handle(StepVisual_StyledItem)::DownCast(theSharing); - if (aSharing->Item() == theOldEntity) - { - aSharing->SetItem(theNewEntity); - return true; - } - return false; -} - -//================================================================================================== - -bool MergeSTEPEntities_CartesianPointProcessor::replaceBSplineCurveWithKnots( - const Handle(StepGeom_CartesianPoint)& theOldEntity, - const Handle(StepGeom_CartesianPoint)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepGeom_BSplineCurveWithKnots) aSharing = - Handle(StepGeom_BSplineCurveWithKnots)::DownCast(theSharing); - bool isReplaced = false; - Handle(StepGeom_HArray1OfCartesianPoint) aControlPoints = aSharing->ControlPointsList(); - for (Standard_Integer anIndex = aControlPoints->Lower(); anIndex <= aControlPoints->Upper(); - ++anIndex) - { - if (aControlPoints->Value(anIndex) == theOldEntity) - { - aControlPoints->SetValue(anIndex, theNewEntity); - isReplaced = true; - } - } - return isReplaced; -} - -//================================================================================================== - -bool MergeSTEPEntities_CartesianPointProcessor::replaceLine( - const Handle(StepGeom_CartesianPoint)& theOldEntity, - const Handle(StepGeom_CartesianPoint)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepGeom_Line) aSharing = Handle(StepGeom_Line)::DownCast(theSharing); - if (aSharing->Pnt() == theOldEntity) - { - aSharing->SetPnt(theNewEntity); - return true; - } - return false; -} - -//================================================================================================== - -bool MergeSTEPEntities_CartesianPointProcessor::replaceBSplineSurfaceWithKnots( - const Handle(StepGeom_CartesianPoint)& theOldEntity, - const Handle(StepGeom_CartesianPoint)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepGeom_BSplineSurfaceWithKnots) aSharing = - Handle(StepGeom_BSplineSurfaceWithKnots)::DownCast(theSharing); - bool isReplaced = false; - Handle(StepGeom_HArray2OfCartesianPoint) aControlPoints = aSharing->ControlPointsList(); - for (Standard_Integer anIndexI = aControlPoints->LowerRow(); - anIndexI <= aControlPoints->UpperRow(); - ++anIndexI) - { - for (Standard_Integer anIndexJ = aControlPoints->LowerCol(); - anIndexJ <= aControlPoints->UpperCol(); - ++anIndexJ) - { - if (aControlPoints->Value(anIndexI, anIndexJ) == theOldEntity) - { - aControlPoints->SetValue(anIndexI, anIndexJ, theNewEntity); - isReplaced = true; - } - } - } - return isReplaced; -} - -//================================================================================================== - -bool MergeSTEPEntities_CartesianPointProcessor::replaceAxis1Placement( - const Handle(StepGeom_CartesianPoint)& theOldEntity, - const Handle(StepGeom_CartesianPoint)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepGeom_Axis1Placement) aSharing = Handle(StepGeom_Axis1Placement)::DownCast(theSharing); - if (aSharing->Location() == theOldEntity) - { - aSharing->SetLocation(theNewEntity); - return true; - } - return false; -} - -//================================================================================================== - -bool MergeSTEPEntities_CartesianPointProcessor::replaceRepresentation( - const Handle(StepGeom_CartesianPoint)& theOldEntity, - const Handle(StepGeom_CartesianPoint)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepRepr_Representation) aSharing = Handle(StepRepr_Representation)::DownCast(theSharing); - bool isReplaced = false; - Handle(StepRepr_HArray1OfRepresentationItem) anItems = aSharing->Items(); - for (Standard_Integer anIndex = 1; anIndex <= aSharing->NbItems(); ++anIndex) - { - const Handle(StepRepr_RepresentationItem) aRepItem = anItems->Value(anIndex); - if (aRepItem == theOldEntity) - { - anItems->SetValue(anIndex, theNewEntity); - isReplaced = true; - } - } - return isReplaced; -} - -//================================================================================================== - -bool MergeSTEPEntities_CartesianPointProcessor::replaceBSplineCurveWithKnotsAndRationalBSplineCurve( - const Handle(StepGeom_CartesianPoint)& theOldEntity, - const Handle(StepGeom_CartesianPoint)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve) aSharing = - Handle(StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve)::DownCast(theSharing); - bool isReplaced = false; - Handle(StepGeom_HArray1OfCartesianPoint) aControlPoints = aSharing->ControlPointsList(); - for (Standard_Integer anIndex = aControlPoints->Lower(); anIndex <= aControlPoints->Upper(); - ++anIndex) - { - if (aControlPoints->Value(anIndex) == theOldEntity) - { - aControlPoints->SetValue(anIndex, theNewEntity); - isReplaced = true; - } - } - return isReplaced; -} - -//================================================================================================== - -bool MergeSTEPEntities_CartesianPointProcessor:: - replaceBSplineSurfaceWithKnotsAndRationalBSplineSurface( - const Handle(StepGeom_CartesianPoint)& theOldEntity, - const Handle(StepGeom_CartesianPoint)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface) aSharing = - Handle(StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface)::DownCast(theSharing); - bool isReplaced = false; - Handle(StepGeom_HArray2OfCartesianPoint) aControlPoints = aSharing->ControlPointsList(); - for (Standard_Integer anIndexI = aControlPoints->LowerRow(); - anIndexI <= aControlPoints->UpperRow(); - ++anIndexI) - { - for (Standard_Integer anIndexJ = aControlPoints->LowerCol(); - anIndexJ <= aControlPoints->UpperCol(); - ++anIndexJ) - { - if (aControlPoints->Value(anIndexI, anIndexJ) == theOldEntity) - { - aControlPoints->SetValue(anIndexI, anIndexJ, theNewEntity); - isReplaced = true; - } - } - } - return isReplaced; -} diff --git a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_CartesianPointProcessor.hxx b/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_CartesianPointProcessor.hxx deleted file mode 100644 index 55c8d72768..0000000000 --- a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_CartesianPointProcessor.hxx +++ /dev/null @@ -1,163 +0,0 @@ -// 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. - -#ifndef _MergeSTEPEntities_CartesianPointProcessor_HeaderFile -#define _MergeSTEPEntities_CartesianPointProcessor_HeaderFile - -#include -#include - -#include - -//! Processor for merging StepGeom_CartesianPoint entities. -//! This processor is responsible for merging Cartesian points with the same coordinates and names. -//! It is used to remove duplicate Cartesian points from the STEP model. -//! See MergeSTEPEntities_EntityProcessor for the description of the processor workflow. -class MergeSTEPEntities_CartesianPointProcessor - : public MergeSTEPEntities_EntityProcessor -{ -public: - //! Constructor. Accepts a work session containing the model to process. - //! Registers replacer functions for all supported sharing entities. - //! @param theWS Work session. - Standard_EXPORT MergeSTEPEntities_CartesianPointProcessor( - const Handle(XSControl_WorkSession)& theWS); - -private: - //! Replaces the old Cartesian point with the new Cartesian point in - //! the sharing StepGeom_Axis2Placement3d. - //! @param theOldEntity Old Cartesian point to replace. - //! @param theNewEntity New Cartesian point to replace the old entity with. - //! @param theSharing The StepGeom_Axis2Placement3d sharing the old entity. - //! @return True if the entity was replaced, false if it was not. - static bool replaceAxis2Placement3d(const Handle(StepGeom_CartesianPoint)& theOldEntity, - const Handle(StepGeom_CartesianPoint)& theNewEntity, - Handle(Standard_Transient) theSharing); - - //! Replaces the old Cartesian point with the new Cartesian point in - //! the sharing StepShape_VertexPoint. - //! @param theOldEntity Old Cartesian point to replace. - //! @param theNewEntity New Cartesian point to replace the old entity with. - //! @param theSharing The StepShape_VertexPoint sharing the old entity. - //! @return True if the entity was replaced, false if it was not. - static bool replaceVertexPoint(const Handle(StepGeom_CartesianPoint)& theOldEntity, - const Handle(StepGeom_CartesianPoint)& theNewEntity, - Handle(Standard_Transient) theSharing); - - //! Replaces the old Cartesian point with the new Cartesian point in - //! the sharing StepShape_GeometricSet. - //! @param theOldEntity Old Cartesian point to replace. - //! @param theNewEntity New Cartesian point to replace the old entity with. - //! @param theSharing The StepShape_GeometricSet sharing the old entity. - //! @return True if the entity was replaced, false if it was not. - static bool replaceGeometricCurveSet(const Handle(StepGeom_CartesianPoint)& theOldEntity, - const Handle(StepGeom_CartesianPoint)& theNewEntity, - Handle(Standard_Transient) theSharing); - - //! Replaces the old Cartesian point with the new Cartesian point in - //! the sharing StepVisual_PresentationLayerAssignment. - //! @param theOldEntity Old Cartesian point to replace. - //! @param theNewEntity New Cartesian point to replace the old entity with. - //! @param theSharing The StepVisual_PresentationLayerAssignment sharing the old entity. - //! @return True if the entity was replaced, false if it was not. - static bool replacePresentationLayerAssignment( - const Handle(StepGeom_CartesianPoint)& theOldEntity, - const Handle(StepGeom_CartesianPoint)& theNewEntity, - Handle(Standard_Transient) theSharing); - - //! Replaces the old Cartesian point with the new Cartesian point in - //! the sharing StepVisual_StyledItem. - //! @param theOldEntity Old Cartesian point to replace. - //! @param theNewEntity New Cartesian point to replace the old entity with. - //! @param theSharing The StepVisual_StyledItem sharing the old entity. - //! @return True if the entity was replaced, false if it was not. - static bool replaceStyledItem(const Handle(StepGeom_CartesianPoint)& theOldEntity, - const Handle(StepGeom_CartesianPoint)& theNewEntity, - Handle(Standard_Transient) theSharing); - - //! Replaces the old Cartesian point with the new Cartesian point in - //! the sharing StepGeom_BSplineCurveWithKnots. - //! @param theOldEntity Old Cartesian point to replace. - //! @param theNewEntity New Cartesian point to replace the old entity with. - //! @param theSharing The StepGeom_BSplineCurveWithKnots sharing the old entity. - //! @return True if the entity was replaced, false if it was not. - static bool replaceBSplineCurveWithKnots(const Handle(StepGeom_CartesianPoint)& theOldEntity, - const Handle(StepGeom_CartesianPoint)& theNewEntity, - Handle(Standard_Transient) theSharing); - - //! Replaces the old Cartesian point with the new Cartesian point in - //! the sharing StepGeom_Line. - //! @param theOldEntity Old Cartesian point to replace. - //! @param theNewEntity New Cartesian point to replace the old entity with. - //! @param theSharing The StepGeom_Line sharing the old entity. - //! @return True if the entity was replaced, false if it was not. - static bool replaceLine(const Handle(StepGeom_CartesianPoint)& theOldEntity, - const Handle(StepGeom_CartesianPoint)& theNewEntity, - Handle(Standard_Transient) theSharing); - - //! Replaces the old Cartesian point with the new Cartesian point in - //! the sharing StepGeom_BSplineSurfaceWithKnots. - //! @param theOldEntity Old Cartesian point to replace. - //! @param theNewEntity New Cartesian point to replace the old entity with. - //! @param theSharing The StepGeom_BSplineSurfaceWithKnots sharing the old entity. - //! @return True if the entity was replaced, false if it was not. - static bool replaceBSplineSurfaceWithKnots(const Handle(StepGeom_CartesianPoint)& theOldEntity, - const Handle(StepGeom_CartesianPoint)& theNewEntity, - Handle(Standard_Transient) theSharing); - - //! Replaces the old Cartesian point with the new Cartesian point in - //! the sharing StepGeom_Axis1Placement. - //! @param theOldEntity Old Cartesian point to replace. - //! @param theNewEntity New Cartesian point to replace the old entity with. - //! @param theSharing The StepGeom_Axis1Placement sharing the old entity. - //! @return True if the entity was replaced, false if it was not. - static bool replaceAxis1Placement(const Handle(StepGeom_CartesianPoint)& theOldEntity, - const Handle(StepGeom_CartesianPoint)& theNewEntity, - Handle(Standard_Transient) theSharing); - - //! Replaces the old Cartesian point with the new Cartesian point in - //! the sharing StepRepr_Representation. - //! @param theOldEntity Old Cartesian point to replace. - //! @param theNewEntity New Cartesian point to replace the old entity with. - //! @param theSharing The StepRepr_Representation sharing the old entity. - //! @return True if the entity was replaced, false if it was not. - static bool replaceRepresentation(const Handle(StepGeom_CartesianPoint)& theOldEntity, - const Handle(StepGeom_CartesianPoint)& theNewEntity, - Handle(Standard_Transient) theSharing); - - //! Replaces the old Cartesian point with the new Cartesian point in - //! the sharing StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve. - //! @param theOldEntity Old Cartesian point to replace. - //! @param theNewEntity New Cartesian point to replace the old entity with. - //! @param theSharing The StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve sharing the old - //! entity. - //! @return True if the entity was replaced, false if it was not. - static bool replaceBSplineCurveWithKnotsAndRationalBSplineCurve( - const Handle(StepGeom_CartesianPoint)& theOldEntity, - const Handle(StepGeom_CartesianPoint)& theNewEntity, - Handle(Standard_Transient) theSharing); - - //! Replaces the old Cartesian point with the new Cartesian point in - //! the sharing StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface. - //! @param theOldEntity Old Cartesian point to replace. - //! @param theNewEntity New Cartesian point to replace the old entity with. - //! @param theSharing The StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface sharing the - //! old entity. - static bool replaceBSplineSurfaceWithKnotsAndRationalBSplineSurface( - const Handle(StepGeom_CartesianPoint)& theOldEntity, - const Handle(StepGeom_CartesianPoint)& theNewEntity, - Handle(Standard_Transient) theSharing); -}; - -#endif // _MergeSTEPEntities_CartesianPointProcessor_HeaderFile diff --git a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_CircleHasher.hxx b/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_CircleHasher.hxx deleted file mode 100644 index 31208dd527..0000000000 --- a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_CircleHasher.hxx +++ /dev/null @@ -1,101 +0,0 @@ -// 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. - -#ifndef _MergeSTEPEntities_CircleHasher_HeaderFile -#define _MergeSTEPEntities_CircleHasher_HeaderFile - -#include -#include - -#include -#include -#include - -//! OCCT-style hasher for StepGeom_Circle entities. -struct MergeSTEPEntities_CircleHasher -{ - //! Returns hash for a Circle entity. - std::size_t operator()(const Handle(StepGeom_Circle)& theCircle) const noexcept - { - const size_t aPositionHash = - !theCircle->Position().Axis2Placement2d().IsNull() - ? MergeSTEPEntities_Axis2Placement2dHasher{}(theCircle->Position().Axis2Placement2d()) - : !theCircle->Position().Axis2Placement3d().IsNull() - ? MergeSTEPEntities_Axis2Placement3dHasher{}(theCircle->Position().Axis2Placement3d()) - : opencascade::MurmurHash::optimalSeed(); - - const size_t aRadiusHash = opencascade::hash(static_cast(theCircle->Radius())); - - const size_t aHashes[2]{aPositionHash, aRadiusHash}; - const size_t aCombinedHash = opencascade::hashBytes(aHashes, sizeof(aHashes)); - if (theCircle->Name().IsNull()) - { - // If the name is not present, return the hash. - return aCombinedHash; - } - // Add the name to the hash if it is present. - const size_t aHashWithName[2]{ - aCombinedHash, - std::hash{}(theCircle->Name()->String())}; - return opencascade::hashBytes(aHashWithName, sizeof(aHashWithName)); - } - - //! Compares two Circle entities. - bool operator()(const Handle(StepGeom_Circle)& theCircle1, - const Handle(StepGeom_Circle)& theCircle2) const noexcept - { - // Compare names. - if (theCircle1->Name().IsNull() != theCircle2->Name().IsNull()) - { - return false; - } - if (!theCircle1->Name()->IsSameString(theCircle2->Name())) - { - return false; - } - - // Compare axis placements. - if (theCircle1->Position().CaseNumber() != theCircle2->Position().CaseNumber()) - { - return false; - } - - if (theCircle1->Position().CaseNumber() == 1) - { - if (!MergeSTEPEntities_Axis2Placement2dHasher{}(theCircle1->Position().Axis2Placement2d(), - theCircle2->Position().Axis2Placement2d())) - { - return false; - } - } - else if (theCircle1->Position().CaseNumber() == 2) - { - if (!MergeSTEPEntities_Axis2Placement3dHasher{}(theCircle1->Position().Axis2Placement3d(), - theCircle2->Position().Axis2Placement3d())) - { - return false; - } - } - - // Compare radius. - constexpr Standard_Real aTolerance = 1e-12; - if (Abs(theCircle1->Radius() - theCircle2->Radius()) > aTolerance) - { - return false; - } - - return true; - } -}; - -#endif // _MergeSTEPEntities_CircleHasher_HeaderFile diff --git a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_CircleProcessor.cxx b/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_CircleProcessor.cxx deleted file mode 100644 index 32dbbc4fc6..0000000000 --- a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_CircleProcessor.cxx +++ /dev/null @@ -1,91 +0,0 @@ -// 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. - -// 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 - -//================================================================================================== - -MergeSTEPEntities_CircleProcessor::MergeSTEPEntities_CircleProcessor( - const Handle(XSControl_WorkSession)& theWS) - : MergeSTEPEntities_EntityProcessor(theWS) -{ - registerReplacer(STANDARD_TYPE(StepShape_EdgeCurve), replaceEdgeCurve); - registerReplacer(STANDARD_TYPE(StepGeom_SurfaceCurve), replaceSurfaceCurve); - registerReplacer(STANDARD_TYPE(StepGeom_SeamCurve), replaceSeamCurve); -} - -//================================================================================================== - -bool MergeSTEPEntities_CircleProcessor::replaceEdgeCurve( - const Handle(StepGeom_Circle)& theOldEntity, - const Handle(StepGeom_Circle)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepShape_EdgeCurve) aSharing = Handle(StepShape_EdgeCurve)::DownCast(theSharing); - if (aSharing->EdgeGeometry() == theOldEntity) - { - aSharing->SetEdgeGeometry(theNewEntity); - return true; - } - return false; -} - -//================================================================================================== - -bool MergeSTEPEntities_CircleProcessor::replaceSurfaceCurve( - const Handle(StepGeom_Circle)& theOldEntity, - const Handle(StepGeom_Circle)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepGeom_SurfaceCurve) aSharing = Handle(StepGeom_SurfaceCurve)::DownCast(theSharing); - if (aSharing->Curve3d() == theOldEntity) - { - aSharing->SetCurve3d(theNewEntity); - return true; - } - return false; -} - -//================================================================================================== - -bool MergeSTEPEntities_CircleProcessor::replaceSeamCurve( - const Handle(StepGeom_Circle)& theOldEntity, - const Handle(StepGeom_Circle)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepGeom_SeamCurve) aSharing = Handle(StepGeom_SeamCurve)::DownCast(theSharing); - if (aSharing->Curve3d() == theOldEntity) - { - aSharing->SetCurve3d(theNewEntity); - return true; - } - return false; -} diff --git a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_CircleProcessor.hxx b/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_CircleProcessor.hxx deleted file mode 100644 index f46c03a3d1..0000000000 --- a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_CircleProcessor.hxx +++ /dev/null @@ -1,64 +0,0 @@ -// 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. - -#ifndef _MergeSTEPEntities_CircleProcessor_HeaderFile -#define _MergeSTEPEntities_CircleProcessor_HeaderFile - -#include -#include - -#include - -//! Processor for merging StepGeom_Circle entities. -//! This processor merges circles with the same position and radius and names. -class MergeSTEPEntities_CircleProcessor - : public MergeSTEPEntities_EntityProcessor -{ -public: - //! Constructor. Stores the work session and registers replacer functions. - //! @param theWS the work session. - Standard_EXPORT MergeSTEPEntities_CircleProcessor(const Handle(XSControl_WorkSession)& theWS); - -private: - //! Replacer function for StepShape_EdgeCurve entities. - //! Replaces the old entity with the new one in the sharing entity. - //! @param theOldEntity the old entity to replace. - //! @param theNewEntity the new entity to replace with. - //! @param theSharing the sharing entity in which to replace the old entity. - //! @return true if the entity was replaced, false otherwise. - static bool replaceEdgeCurve(const Handle(StepGeom_Circle)& theOldEntity, - const Handle(StepGeom_Circle)& theNewEntity, - Handle(Standard_Transient) theSharing); - - //! Replacer function for StepGeom_SurfaceCurve entities. - //! Replaces the old entity with the new one in the sharing entity. - //! @param theOldEntity the old entity to replace. - //! @param theNewEntity the new entity to replace with. - //! @param theSharing the sharing entity in which to replace the old entity. - //! @return true if the entity was replaced, false otherwise. - static bool replaceSurfaceCurve(const Handle(StepGeom_Circle)& theOldEntity, - const Handle(StepGeom_Circle)& theNewEntity, - Handle(Standard_Transient) theSharing); - - //! Replacer function for StepGeom_SeamCurve entities. - //! Replaces the old entity with the new one in the sharing entity. - //! @param theOldEntity the old entity to replace. - //! @param theNewEntity the new entity to replace with. - //! @param theSharing the sharing entity in which to replace the old entity. - //! @return true if the entity was replaced, false otherwise. - static bool replaceSeamCurve(const Handle(StepGeom_Circle)& theOldEntity, - const Handle(StepGeom_Circle)& theNewEntity, - Handle(Standard_Transient) theSharing); -}; - -#endif // _MergeSTEPEntities_CircleProcessor_HeaderFile diff --git a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_DirectionHasher.hxx b/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_DirectionHasher.hxx deleted file mode 100644 index a9a93c56ad..0000000000 --- a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_DirectionHasher.hxx +++ /dev/null @@ -1,78 +0,0 @@ -// 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. - -#ifndef _MergeSTEPEntities_DirectionHasher_HeaderFile -#define _MergeSTEPEntities_DirectionHasher_HeaderFile - -#include -#include -#include - -//! OCCT-style hasher for StepGeom_Direction entities. -struct MergeSTEPEntities_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(aCoords->Value(anIndex)); - } - // If direction has no name, hash only direction ratios. - if (theDirection->Name().IsNull()) - { - return opencascade::hashBytes(anArray, sizeof(anArray)); - } - // Otherwise, hash both direction ratios and name. - const size_t aHashes[2]{opencascade::hashBytes(anArray, sizeof(anArray)), - std::hash{}(theDirection->Name()->String())}; - return opencascade::hashBytes(aHashes, sizeof(aHashes)); - } - - // Compares two directions by their names and direction ratios. - bool operator()(const Handle(StepGeom_Direction)& theDirection1, - const Handle(StepGeom_Direction)& theDirection2) const noexcept - { - // Compare names. - if (theDirection1->Name().IsNull() != theDirection2->Name().IsNull()) - { - return false; - } - if (!theDirection1->Name()->IsSameString(theDirection2->Name())) - { - return false; - } - - // 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()) - { - return false; - } - for (Standard_Integer i = aCoords1->Lower(); i <= aCoords1->Upper(); ++i) - { - if (std::abs(aCoords1->Value(i) - aCoords2->Value(i)) > aTolerance) - { - return false; - } - } - return true; - } -}; - -#endif // _MergeSTEPEntities_DirectionHasher_HeaderFile diff --git a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_DirectionProcessor.cxx b/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_DirectionProcessor.cxx deleted file mode 100644 index c561818db8..0000000000 --- a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_DirectionProcessor.cxx +++ /dev/null @@ -1,98 +0,0 @@ -// 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. - -// 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 - -//================================================================================================== - -MergeSTEPEntities_DirectionProcessor::MergeSTEPEntities_DirectionProcessor( - const Handle(XSControl_WorkSession)& theWS) - : MergeSTEPEntities_EntityProcessor( - theWS) -{ - registerReplacer(STANDARD_TYPE(StepGeom_Axis1Placement), replaceAxis1Placement); - registerReplacer(STANDARD_TYPE(StepGeom_Axis2Placement3d), replaceAxis2Placement3d); - registerReplacer(STANDARD_TYPE(StepGeom_Vector), replaceVector); -} - -//================================================================================================== - -bool MergeSTEPEntities_DirectionProcessor::replaceAxis1Placement( - const Handle(StepGeom_Direction)& theOldEntity, - const Handle(StepGeom_Direction)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepGeom_Axis1Placement) aSharing = Handle(StepGeom_Axis1Placement)::DownCast(theSharing); - if (aSharing->Axis() == theOldEntity) - { - aSharing->SetAxis(theNewEntity); - return true; - } - return false; -} - -//================================================================================================== - -bool MergeSTEPEntities_DirectionProcessor::replaceAxis2Placement3d( - const Handle(StepGeom_Direction)& theOldEntity, - const Handle(StepGeom_Direction)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepGeom_Axis2Placement3d) aSharing = - Handle(StepGeom_Axis2Placement3d)::DownCast(theSharing); - if (aSharing->Axis() == theOldEntity) - { - aSharing->SetAxis(theNewEntity); - return true; - } - else if (aSharing->RefDirection() == theOldEntity) - { - aSharing->SetRefDirection(theNewEntity); - return true; - } - return false; -} - -//================================================================================================== - -bool MergeSTEPEntities_DirectionProcessor::replaceVector( - const Handle(StepGeom_Direction)& theOldEntity, - const Handle(StepGeom_Direction)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepGeom_Vector) aSharing = Handle(StepGeom_Vector)::DownCast(theSharing); - if (aSharing->Orientation() == theOldEntity) - { - aSharing->SetOrientation(theNewEntity); - return true; - } - return false; -} diff --git a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_DirectionProcessor.hxx b/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_DirectionProcessor.hxx deleted file mode 100644 index 2e69e5a69f..0000000000 --- a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_DirectionProcessor.hxx +++ /dev/null @@ -1,65 +0,0 @@ -// 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. - -#ifndef _MergeSTEPEntities_DirectionProcessor_HeaderFile -#define _MergeSTEPEntities_DirectionProcessor_HeaderFile - -#include -#include - -#include - -//! Processor for merging StepGeom_Direction entities. -//! This processor merges directions with the same direction ratios and names. -//! The processor replaces all occurrences of the old directions with the new ones. -//! The processor does not remove old directions from the model. -//! See MergeSTEPEntities_EntityProcessor for the description of the processor workflow. -class MergeSTEPEntities_DirectionProcessor - : public MergeSTEPEntities_EntityProcessor -{ -public: - //! Constructor. Stores the work session and registers replacer functions. - //! @param theWS the work session. - Standard_EXPORT MergeSTEPEntities_DirectionProcessor(const Handle(XSControl_WorkSession)& theWS); - -private: - //! Replaces the old direction with the new one in the StepGeom_Axis1Placement entity. - //! @param theOldEntity the old direction. - //! @param theNewEntity the new direction. - //! @param theSharing the StepGeom_Axis1Placement entity to update. - //! @return true if the direction was replaced, false otherwise. - static bool replaceAxis1Placement(const Handle(StepGeom_Direction)& theOldEntity, - const Handle(StepGeom_Direction)& theNewEntity, - Handle(Standard_Transient) theSharing); - - //! Replaces the old direction with the new one in the StepGeom_Axis2Placement3d entity. - //! @param theOldEntity the old direction. - //! @param theNewEntity the new direction. - //! @param theSharing the StepGeom_Axis2Placement3d entity to update. - //! @return true if the direction was replaced, false otherwise. - static bool replaceAxis2Placement3d(const Handle(StepGeom_Direction)& theOldEntity, - const Handle(StepGeom_Direction)& theNewEntity, - Handle(Standard_Transient) theSharing); - - //! Replaces the old direction with the new one in the StepGeom_Vector entity. - //! @param theOldEntity the old direction. - //! @param theNewEntity the new direction. - //! @param theSharing the StepGeom_Vector entity to update. - //! @return true if the direction was replaced, false otherwise. - static bool replaceVector(const Handle(StepGeom_Direction)& theOldEntity, - const Handle(StepGeom_Direction)& theNewEntity, - Handle(Standard_Transient) theSharing); -}; - -#endif // _MergeSTEPEntities_DirectionProcessor_HeaderFile diff --git a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_EntityProcessor.hxx b/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_EntityProcessor.hxx deleted file mode 100644 index 66f1f03496..0000000000 --- a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_EntityProcessor.hxx +++ /dev/null @@ -1,241 +0,0 @@ -// 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. - -#ifndef _MergeSTEPEntities_EntityProcessor_HeaderFile -#define _MergeSTEPEntities_EntityProcessor_HeaderFile - -#include -#include -#include -#include -#include -#include - -#include - -//! Base class for removing duplicate entities. -//! Implements the logic of processing entities and removing duplicates. -//! Child classes should only implement and register replacer functions -//! for each specific type of sharing entity. -//! How to use: -//! 1. Create an instance of the child class. -//! 2. Add entities to the processor using ProcessEntity() method. Entities -//! that can be merged will be stored in the internal map, others will be ignored. -//! 3. Call Perform() method to replace duplicate entities. After this call -//! all duplicate entities will be replaced in a model with the first processed entity -//! that is evaluated as equal to them. -//! IMPORTANT: Duplicated entities will be replaced but not removed from the model! -//! 4. Call GetReplacedEntities() to get a list of replaced duplicates. This list can be used -//! to remove entities from the model. -//! @tparam ProcessedType Type of the processed entities. -//! @tparam ProcessedTypeHasher OCCT-Style hasher for the processed entities. -template -class MergeSTEPEntities_EntityProcessor -{ -protected: - // Map of duplicate entities. Key is the first processed entity, value is a list of duplicates. - using DuplicateMap = NCollection_DataMap, - ProcessedTypeHasher>; - // Function to replace an entity in sharings. First argument is the old entity, second is the new - // entity, third is the sharing in which the entity should be replaced. Returns true if the entity - // was replaced, false otherwise. - using ReplacerFunction = std::function; - // Map of replacer functions. Key is the type of the sharing entity, value is the replacer - // function for this type. - using ReplacerMap = NCollection_DataMap; - -protected: - //! Constructor. Accepts a work session containing the model to process. - //! Protected to prevent direct instantiation of the base class. Only child classes should be - //! allowed to instantiate. - //! @param theWS Work session. - MergeSTEPEntities_EntityProcessor(const Handle(XSControl_WorkSession)& theWS); - -public: - //! Function to process an entity. If the entity can be merged, it will be stored in the internal - //! map. If the entity cannot be merged, it will be ignored. - //! Entity can only be processed if: - //! 1. The type of entity is ProcessedType. - //! 2. All sharings of the entity have a registered replacer function. - //! @param theEntity Entity to process. - //! @return True if the entity was processed, false if it was ignored. - Standard_EXPORT bool ProcessEntity(const Handle(Standard_Transient)& theEntity); - - //! Function to replace duplicate entities. After this call, all duplicate entities will be - //! replaced with the first processed entity that is evaluated as equal to them. - //! IMPORTANT: Duplicated entities will be replaced but not removed from the model! - //! @param theReplacedEntities List where replaced entities will be stored. - //! This list can be used to remove entities from the model. - Standard_EXPORT void Perform(TColStd_MapOfTransient& theReplacedEntities); - -protected: - //! Register a replacer function for a specific type of sharing entity. - //! Should be used by child classes to register replacer functions for each specific type of - //! sharing entity. If a sharing entity of the specified type is encountered during processing, - //! the registered replacer function will be called to replace the old entity with the new one. - //! All replacers must be registered before calling ProcessEntity() method. - //! @param theType Type of the sharing entity. - //! @param theReplacer Replacer function. - void registerReplacer(const Handle(Standard_Type)& theType, const ReplacerFunction& theReplacer); - -public: - //! Checks if all sharings have registered replacers for their types. - //! @param theSharings List of sharings to check. - //! @return True if all sharings have registered replacers, false otherwise. - bool hasAllReplacers(const Handle(TColStd_HSequenceOfTransient)& theSharings) const; - - //! Replaces an old entity with a new entity in sharings. - //! Should only be called if all sharings have registered replacers. - //! @param theOldEntity Old entity to replace. - //! @param theNewEntity New entity to replace old entity with. - //! @param theSharings List of old entity sharings to replace the entity in. - //! @return True if all entities were replaced, false if at least one entity was not replaced. - bool replaceInSharings(const Handle(ProcessedType)& theOldEntity, - const Handle(ProcessedType)& theNewEntity, - const Handle(TColStd_HSequenceOfTransient)& theSharings) const; - -private: - Handle(XSControl_WorkSession) myWS; //!< Work session. - ReplacerMap myReplacerMap; //!< Map of replacer functions. - DuplicateMap myDuplicateMap; //!< Map of duplicate entities. -}; - -//================================================================================================== - -template -MergeSTEPEntities_EntityProcessor:: - MergeSTEPEntities_EntityProcessor(const Handle(XSControl_WorkSession)& theWS) - : myWS(theWS), - myReplacerMap(), - myDuplicateMap() -{ -} - -//================================================================================================== - -template -bool MergeSTEPEntities_EntityProcessor::ProcessEntity( - const Handle(Standard_Transient)& theEntity) -{ - const Handle(ProcessedType) anEntity = Handle(ProcessedType)::DownCast(theEntity); - if (anEntity.IsNull()) - { - return false; - } - const Interface_Graph& aGraph = myWS->Graph(); - const Handle(TColStd_HSequenceOfTransient) aSharings = aGraph.GetSharings(anEntity); - if (hasAllReplacers(aSharings)) - { - std::vector* anIter = myDuplicateMap.ChangeSeek(anEntity); - if (anIter == nullptr) - { - // Add as a new key. - myDuplicateMap.Bind(anEntity, std::vector{}); - } - else - { - // Add as a value. - anIter->push_back(anEntity); - } - } - - return true; -} - -//================================================================================================== - -template -void MergeSTEPEntities_EntityProcessor::Perform( - TColStd_MapOfTransient& theReplacedEntities) -{ - for (typename DuplicateMap::Iterator anIter(myDuplicateMap); anIter.More(); anIter.Next()) - { - const Handle(ProcessedType)& anEntity = anIter.Key(); - const std::vector& aDuplicates = anIter.Value(); - if (aDuplicates.empty()) - { - continue; - } - - const Interface_Graph& aGraph = myWS->Graph(); - for (const auto& aDuplicate : aDuplicates) - { - Handle(TColStd_HSequenceOfTransient) aSharings = aGraph.GetSharings(aDuplicate); - if (aSharings.IsNull()) - { - continue; - } - - if (replaceInSharings(aDuplicate, anEntity, aSharings)) - { - theReplacedEntities.Add(aDuplicate); - } - } - } -} - -//================================================================================================== - -template -void MergeSTEPEntities_EntityProcessor::registerReplacer( - const Handle(Standard_Type)& theType, - const ReplacerFunction& theReplacer) -{ - myReplacerMap.Bind(theType, theReplacer); -} - -//================================================================================================== - -template -bool MergeSTEPEntities_EntityProcessor::hasAllReplacers( - const Handle(TColStd_HSequenceOfTransient)& theSharings) const -{ - if (theSharings.IsNull()) - { - return false; - } - return std::all_of(theSharings->cbegin(), - theSharings->cend(), - [this](const Handle(Standard_Transient)& theSharing) { - return myReplacerMap.IsBound(theSharing->DynamicType()); - }); -} - -//================================================================================================== -template -bool MergeSTEPEntities_EntityProcessor::replaceInSharings( - const Handle(ProcessedType)& theOldEntity, - const Handle(ProcessedType)& theNewEntity, - const Handle(TColStd_HSequenceOfTransient)& theSharings) const -{ - bool isAllReplaced = true; - for (const auto& aSharing : *theSharings) - { - if (aSharing.IsNull()) - { - continue; - } - - const ReplacerFunction& aReplacer = myReplacerMap.Find(aSharing->DynamicType()); - if (!aReplacer(theOldEntity, theNewEntity, aSharing)) - { - isAllReplaced = false; - } - } - return isAllReplaced; -} - -#endif // _MergeSTEPEntities_EntityProcessor_HeaderFile diff --git a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_LineHasher.hxx b/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_LineHasher.hxx deleted file mode 100644 index 3533d55af2..0000000000 --- a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_LineHasher.hxx +++ /dev/null @@ -1,77 +0,0 @@ -// 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. - -#ifndef _MergeSTEPEntities_LineHasher_HeaderFile -#define _MergeSTEPEntities_LineHasher_HeaderFile - -#include -#include - -#include -#include -#include - -//! OCCT-style hasher for StepGeom_Line entities. -struct MergeSTEPEntities_LineHasher -{ - // Hashes the Line by its name and Line ratios. - std::size_t operator()(const Handle(StepGeom_Line)& theLine) const noexcept - { - const size_t aHashes[2]{MergeSTEPEntities_CartesianPointHasher{}(theLine->Pnt()), - MergeSTEPEntities_VectorHasher{}(theLine->Dir())}; - - const size_t aCombinedHash = opencascade::hashBytes(aHashes, sizeof(aHashes)); - if (theLine->Name().IsNull()) - { - // If the name is not present, return the hash. - return aCombinedHash; - } - // Add the name to the hash if it is present. - const size_t aCombinedHashWithName[2]{ - aCombinedHash, - std::hash{}(theLine->Name()->String())}; - return opencascade::hashBytes(aCombinedHashWithName, sizeof(aCombinedHashWithName)); - } - - // Compares two Lines by their names and Line ratios. - bool operator()(const Handle(StepGeom_Line)& theLine1, - const Handle(StepGeom_Line)& theLine2) const noexcept - - { - // Compare names. - if (theLine1->Name().IsNull() != theLine2->Name().IsNull()) - { - return false; - } - if (!theLine1->Name()->IsSameString(theLine2->Name())) - { - return false; - } - - // Compare points. - if (!MergeSTEPEntities_CartesianPointHasher{}(theLine1->Pnt(), theLine2->Pnt())) - { - return false; - } - - // Compare directions. - if (!MergeSTEPEntities_VectorHasher{}(theLine1->Dir(), theLine2->Dir())) - { - return false; - } - - return true; - } -}; - -#endif // _MergeSTEPEntities_LineHasher_HeaderFile diff --git a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_LineProcessor.cxx b/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_LineProcessor.cxx deleted file mode 100644 index 03f9d02ea9..0000000000 --- a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_LineProcessor.cxx +++ /dev/null @@ -1,131 +0,0 @@ -// 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. - -// 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 - -//================================================================================================== - -MergeSTEPEntities_LineProcessor::MergeSTEPEntities_LineProcessor( - const Handle(XSControl_WorkSession)& theWS) - : MergeSTEPEntities_EntityProcessor(theWS) -{ - registerReplacer(STANDARD_TYPE(StepShape_EdgeCurve), replaceEdgeCurve); - registerReplacer(STANDARD_TYPE(StepGeom_TrimmedCurve), replaceTrimmedCurve); - registerReplacer(STANDARD_TYPE(StepGeom_SurfaceCurve), replaceSurfaceCurve); - registerReplacer(STANDARD_TYPE(StepRepr_DefinitionalRepresentation), - replaceDefinitionalRepresentation); - registerReplacer(STANDARD_TYPE(StepGeom_SeamCurve), replaceSeamCurve); -} - -//================================================================================================== - -bool MergeSTEPEntities_LineProcessor::replaceEdgeCurve(const Handle(StepGeom_Line)& theOldEntity, - const Handle(StepGeom_Line)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepShape_EdgeCurve) aSharing = Handle(StepShape_EdgeCurve)::DownCast(theSharing); - if (aSharing->EdgeGeometry() == theOldEntity) - { - aSharing->SetEdgeGeometry(theNewEntity); - return true; - } - return false; -} - -//================================================================================================== - -bool MergeSTEPEntities_LineProcessor::replaceTrimmedCurve(const Handle(StepGeom_Line)& theOldEntity, - const Handle(StepGeom_Line)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepGeom_TrimmedCurve) aSharing = Handle(StepGeom_TrimmedCurve)::DownCast(theSharing); - if (aSharing->BasisCurve() == theOldEntity) - { - aSharing->SetBasisCurve(theNewEntity); - return true; - } - return false; -} - -//================================================================================================== - -bool MergeSTEPEntities_LineProcessor::replaceSurfaceCurve(const Handle(StepGeom_Line)& theOldEntity, - const Handle(StepGeom_Line)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepGeom_SurfaceCurve) aSharing = Handle(StepGeom_SurfaceCurve)::DownCast(theSharing); - if (aSharing->Curve3d() == theOldEntity) - { - aSharing->SetCurve3d(theNewEntity); - return true; - } - return false; -} - -//================================================================================================== - -bool MergeSTEPEntities_LineProcessor::replaceDefinitionalRepresentation( - const Handle(StepGeom_Line)& theOldEntity, - const Handle(StepGeom_Line)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepRepr_DefinitionalRepresentation) aSharing = - Handle(StepRepr_DefinitionalRepresentation)::DownCast(theSharing); - bool isReplaced = false; - Handle(StepRepr_HArray1OfRepresentationItem) anItems = aSharing->Items(); - for (Standard_Integer anIndex = 1; anIndex <= aSharing->NbItems(); ++anIndex) - { - const Handle(StepRepr_RepresentationItem) aRepItem = anItems->Value(anIndex); - if (aRepItem == theOldEntity) - { - anItems->SetValue(anIndex, theNewEntity); - isReplaced = true; - } - } - return isReplaced; -} - -//================================================================================================== - -bool MergeSTEPEntities_LineProcessor::replaceSeamCurve(const Handle(StepGeom_Line)& theOldEntity, - const Handle(StepGeom_Line)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepGeom_SeamCurve) aSharing = Handle(StepGeom_SeamCurve)::DownCast(theSharing); - if (aSharing->Curve3d() == theOldEntity) - { - aSharing->SetCurve3d(theNewEntity); - return true; - } - return false; -} diff --git a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_LineProcessor.hxx b/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_LineProcessor.hxx deleted file mode 100644 index 791ef42189..0000000000 --- a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_LineProcessor.hxx +++ /dev/null @@ -1,84 +0,0 @@ -// 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. - -#ifndef _MergeSTEPEntities_LineProcessor_HeaderFile -#define _MergeSTEPEntities_LineProcessor_HeaderFile - -#include -#include - -#include - -//! Processor for merging StepGeom_Line entities. -//! This processor merges lines with the same point and direction and names. -class MergeSTEPEntities_LineProcessor - : public MergeSTEPEntities_EntityProcessor -{ -public: - //! Constructor. Stores the work session and registers replacer functions. - //! @param theWS the work session. - Standard_EXPORT MergeSTEPEntities_LineProcessor(const Handle(XSControl_WorkSession)& theWS); - -private: - //! Replacer function for StepShape_EdgeCurve entities. - //! Replaces the old entity with the new one in the sharing entity. - //! @param theOldEntity the old entity to replace. - //! @param theNewEntity the new entity to replace with. - //! @param theSharing the sharing entity in which to replace the old entity. - //! @return true if the entity was replaced, false otherwise. - static bool replaceEdgeCurve(const Handle(StepGeom_Line)& theOldEntity, - const Handle(StepGeom_Line)& theNewEntity, - Handle(Standard_Transient) theSharing); - - //! Replacer function for StepGeom_TrimmedCurve entities. - //! Replaces the old entity with the new one in the sharing entity. - //! @param theOldEntity the old entity to replace. - //! @param theNewEntity the new entity to replace with. - //! @param theSharing the sharing entity in which to replace the old entity. - //! @return true if the entity was replaced, false otherwise. - static bool replaceTrimmedCurve(const Handle(StepGeom_Line)& theOldEntity, - const Handle(StepGeom_Line)& theNewEntity, - Handle(Standard_Transient) theSharing); - - //! Replacer function for StepGeom_SurfaceCurve entities. - //! Replaces the old entity with the new one in the sharing entity. - //! @param theOldEntity the old entity to replace. - //! @param theNewEntity the new entity to replace with. - //! @param theSharing the sharing entity in which to replace the old entity. - //! @return true if the entity was replaced, false otherwise. - static bool replaceSurfaceCurve(const Handle(StepGeom_Line)& theOldEntity, - const Handle(StepGeom_Line)& theNewEntity, - Handle(Standard_Transient) theSharing); - - //! Replacer function for StepRepr_DefinitionalRepresentation entities. - //! Replaces the old entity with the new one in the sharing entity. - //! @param theOldEntity the old entity to replace. - //! @param theNewEntity the new entity to replace with. - //! @param theSharing the sharing entity in which to replace the old entity. - //! @return true if the entity was replaced, false otherwise. - static bool replaceDefinitionalRepresentation(const Handle(StepGeom_Line)& theOldEntity, - const Handle(StepGeom_Line)& theNewEntity, - Handle(Standard_Transient) theSharing); - - //! Replacer function for StepGeom_SeamCurve entities. - //! Replaces the old entity with the new one in the sharing entity. - //! @param theOldEntity the old entity to replace. - //! @param theNewEntity the new entity to replace with. - //! @param theSharing the sharing entity in which to replace the old entity. - //! @return true if the entity was replaced, false otherwise. - static bool replaceSeamCurve(const Handle(StepGeom_Line)& theOldEntity, - const Handle(StepGeom_Line)& theNewEntity, - Handle(Standard_Transient) theSharing); -}; - -#endif // _MergeSTEPEntities_LineProcessor_HeaderFile diff --git a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_Merger.cxx b/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_Merger.cxx deleted file mode 100644 index 044c98548e..0000000000 --- a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_Merger.cxx +++ /dev/null @@ -1,123 +0,0 @@ -// 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 - -//================================================================================================== - -MergeSTEPEntities_Merger::MergeSTEPEntities_Merger(Handle(XSControl_WorkSession) theWS) - : myWS(theWS) -{ -} - -//================================================================================================== - -void MergeSTEPEntities_Merger::Perform() -{ - Handle(StepData_StepModel) aModel = Handle(StepData_StepModel)::DownCast(myWS->Model()); - if (aModel.IsNull()) - { - return; - } - - //! Initialize processors. - MergeSTEPEntities_CartesianPointProcessor aCartesianPointProcessor(myWS); - MergeSTEPEntities_DirectionProcessor aDirectionProcessor(myWS); - MergeSTEPEntities_Axis2Placement3dProcessor aAxis2Placement3dProcessor(myWS); - MergeSTEPEntities_VectorProcessor aVectorProcessor(myWS); - MergeSTEPEntities_LineProcessor aLineProcessor(myWS); - MergeSTEPEntities_PlaneProcessor aPlaneProcessor(myWS); - MergeSTEPEntities_CircleProcessor aCircleProcessor(myWS); - - // Process all entities. - for (Standard_Integer anIndex = 1; anIndex <= aModel->NbEntities(); ++anIndex) - { - const Handle(Standard_Transient) anEntity = aModel->Value(anIndex); - aCartesianPointProcessor.ProcessEntity(anEntity); - aDirectionProcessor.ProcessEntity(anEntity); - aAxis2Placement3dProcessor.ProcessEntity(anEntity); - aVectorProcessor.ProcessEntity(anEntity); - aLineProcessor.ProcessEntity(anEntity); - aPlaneProcessor.ProcessEntity(anEntity); - aCircleProcessor.ProcessEntity(anEntity); - } - - // Perform replacement of duplicate entities. - TColStd_MapOfTransient aReplacedEntities; - aCartesianPointProcessor.Perform(aReplacedEntities); - aDirectionProcessor.Perform(aReplacedEntities); - aAxis2Placement3dProcessor.Perform(aReplacedEntities); - aVectorProcessor.Perform(aReplacedEntities); - aLineProcessor.Perform(aReplacedEntities); - aPlaneProcessor.Perform(aReplacedEntities); - aCircleProcessor.Perform(aReplacedEntities); - - // Remove duplicate entities. - removeEntities(aReplacedEntities); -} - -//================================================================================================== - -void MergeSTEPEntities_Merger::removeEntities(const TColStd_MapOfTransient& theToRemove) -{ - if (theToRemove.IsEmpty()) - { - return; - } - // Remove entities. - Handle(StepData_StepModel) anIntermediateModel = new StepData_StepModel(); - Handle(StepData_StepModel) aReadModel = Handle(StepData_StepModel)::DownCast(myWS->Model()); - anIntermediateModel->SetProtocol(aReadModel->Protocol()); - anIntermediateModel->SetGTool(aReadModel->GTool()); - - for (Standard_Integer i = 1; i <= aReadModel->NbEntities(); i++) - { - const Handle(Standard_Transient)& anEnt = aReadModel->Value(i); - if (!theToRemove.Contains(anEnt)) - { - anIntermediateModel->AddWithRefs(anEnt); - } - } - - myWS->SetModel(anIntermediateModel); - myWS->ComputeGraph(); - - // Clean hanged entities. - Handle(StepData_StepModel) aNewModel = new StepData_StepModel(); - aNewModel->SetProtocol(anIntermediateModel->Protocol()); - aNewModel->SetGTool(anIntermediateModel->GTool()); - const auto& aGraph = myWS->Graph(); - - for (Standard_Integer i = 1; i <= anIntermediateModel->NbEntities(); i++) - { - const Handle(Standard_Transient)& anEnt = anIntermediateModel->Value(i); - if (aGraph.Shareds(anEnt).NbEntities() > 0 || aGraph.Sharings(anEnt).NbEntities() > 0) - { - aNewModel->AddWithRefs(anEnt); - } - } - - myWS->SetModel(aNewModel); - myWS->ComputeGraph(); -} diff --git a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_Merger.hxx b/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_Merger.hxx deleted file mode 100644 index 436ea414a6..0000000000 --- a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_Merger.hxx +++ /dev/null @@ -1,46 +0,0 @@ -// 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. - -#ifndef _MergeSTEPEntities_Merger_HeaderFile -#define _MergeSTEPEntities_Merger_HeaderFile - -#include - -class XSControl_WorkSession; - -//! A class to merge STEP entities. -//! This class is used to merge equal STEP entities in the work session and remove duplicates. -//! More detailed information about merging entities cam be found in -//! MergeSTEPEntities_EntityProcessor class and its descendants. -class MergeSTEPEntities_Merger -{ -public: - //! Constructor. - //! @param theWS the work session to merge entities in. - Standard_EXPORT MergeSTEPEntities_Merger(Handle(XSControl_WorkSession) theWS); - - //! Perform the merging of entities. - //! All entities in a model stored in the provided work session that are considered equal to - //! each other will be merged, and duplicates will be removed. - Standard_EXPORT void Perform(); - -private: - //! Remove entities from the work session. - //! @param theToRemove the entities to remove. - void removeEntities(const TColStd_MapOfTransient& theToRemove); - -private: - Handle(XSControl_WorkSession) myWS; //!< The work session containing the model with entities. -}; - -#endif // _MergeSTEPEntities_Merger_HeaderFile diff --git a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_PlaneHasher.hxx b/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_PlaneHasher.hxx deleted file mode 100644 index 3e8ab9ab94..0000000000 --- a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_PlaneHasher.hxx +++ /dev/null @@ -1,60 +0,0 @@ -// 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. - -#ifndef _MergeSTEPEntities_PlaneHasher_HeaderFile -#define _MergeSTEPEntities_PlaneHasher_HeaderFile - -#include - -#include -#include - -//! OCCT-style hasher for StepGeom_Plane entities. -struct MergeSTEPEntities_PlaneHasher -{ - // Hashes the axis Planes. - std::size_t operator()(const Handle(StepGeom_Plane)& thePlane) const noexcept - { - const size_t aHash = MergeSTEPEntities_Axis2Placement3dHasher{}(thePlane->Position()); - if (thePlane->Name().IsNull()) - { - // If the name is not present, return the hash. - return aHash; - } - // Add the name to the hash if it is present. - const size_t aCombinedHashWithName[2]{ - aHash, - std::hash{}(thePlane->Name()->String())}; - return opencascade::hashBytes(aCombinedHashWithName, sizeof(aCombinedHashWithName)); - } - - // Compares two axis Planes. - bool operator()(const Handle(StepGeom_Plane)& thePlane1, - const Handle(StepGeom_Plane)& thePlane2) const noexcept - { - // Compare names. - if (thePlane1->Name().IsNull() != thePlane2->Name().IsNull()) - { - return false; - } - if (!thePlane1->Name()->IsSameString(thePlane2->Name())) - { - return false; - } - - // Compare axis Planes. - return MergeSTEPEntities_Axis2Placement3dHasher{}(thePlane1->Position(), thePlane2->Position()); - } -}; - -#endif // _MergeSTEPEntities_PlaneHasher_HeaderFile diff --git a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_PlaneProcessor.cxx b/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_PlaneProcessor.cxx deleted file mode 100644 index 24ec850ea4..0000000000 --- a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_PlaneProcessor.cxx +++ /dev/null @@ -1,57 +0,0 @@ -// 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 - -//================================================================================================== - -MergeSTEPEntities_PlaneProcessor::MergeSTEPEntities_PlaneProcessor( - const Handle(XSControl_WorkSession)& theWS) - : MergeSTEPEntities_EntityProcessor(theWS) -{ - registerReplacer(STANDARD_TYPE(StepShape_AdvancedFace), replaceAdvancedFace); - registerReplacer(STANDARD_TYPE(StepGeom_Pcurve), replacePcurve); -} - -//================================================================================================== - -bool MergeSTEPEntities_PlaneProcessor::replaceAdvancedFace( - const Handle(StepGeom_Plane)& theOldEntity, - const Handle(StepGeom_Plane)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepShape_AdvancedFace) aSharing = Handle(StepShape_AdvancedFace)::DownCast(theSharing); - if (aSharing->FaceGeometry() == theOldEntity) - { - aSharing->SetFaceGeometry(theNewEntity); - return true; - } - return false; -} - -//================================================================================================== -bool MergeSTEPEntities_PlaneProcessor::replacePcurve(const Handle(StepGeom_Plane)& theOldEntity, - const Handle(StepGeom_Plane)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepGeom_Pcurve) aSharing = Handle(StepGeom_Pcurve)::DownCast(theSharing); - if (aSharing->BasisSurface() == theOldEntity) - { - aSharing->SetBasisSurface(theNewEntity); - return true; - } - return false; -} diff --git a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_PlaneProcessor.hxx b/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_PlaneProcessor.hxx deleted file mode 100644 index 44dde07449..0000000000 --- a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_PlaneProcessor.hxx +++ /dev/null @@ -1,54 +0,0 @@ -// 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. - -#ifndef _MergeSTEPEntities_PlaneProcessor_HeaderFile -#define _MergeSTEPEntities_PlaneProcessor_HeaderFile - -#include -#include - -#include - -//! Processor for merging StepGeom_Plane entities. -//! This processor merges planes with the same names and placements. -class MergeSTEPEntities_PlaneProcessor - : public MergeSTEPEntities_EntityProcessor -{ -public: - //! Constructor. Stores the work session and registers replacer functions. - //! @param theWS the work session. - Standard_EXPORT MergeSTEPEntities_PlaneProcessor(const Handle(XSControl_WorkSession)& theWS); - -private: - //! Replacer function for StepShape_AdvancedFace entities. - //! Replaces the old entity with the new one in the sharing entity. - //! @param theOldEntity the old entity to replace. - //! @param theNewEntity the new entity to replace with. - //! @param theSharing the sharing StepShape_AdvancedFace in which to replace the old entity. - //! @return true if the entity was replaced, false otherwise. - static bool replaceAdvancedFace(const Handle(StepGeom_Plane)& theOldEntity, - const Handle(StepGeom_Plane)& theNewEntity, - Handle(Standard_Transient) theSharing); - - //! Replacer function for StepGeom_Pcurve entities. - //! Replaces the old entity with the new one in the sharing entity. - //! @param theOldEntity the old entity to replace. - //! @param theNewEntity the new entity to replace with. - //! @param theSharing the sharing StepGeom_Pcurve in which to replace the old entity. - //! @return true if the entity was replaced, false otherwise. - static bool replacePcurve(const Handle(StepGeom_Plane)& theOldEntity, - const Handle(StepGeom_Plane)& theNewEntity, - Handle(Standard_Transient) theSharing); -}; - -#endif // _MergeSTEPEntities_DirectionProcessor_HeaderFile diff --git a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_VectorHasher.hxx b/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_VectorHasher.hxx deleted file mode 100644 index 2144b1ded2..0000000000 --- a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_VectorHasher.hxx +++ /dev/null @@ -1,71 +0,0 @@ -// 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. - -#ifndef _MergeSTEPEntities_VectorHasher_HeaderFile -#define _MergeSTEPEntities_VectorHasher_HeaderFile - -#include - -#include -#include -#include - -//! OCCT-style hasher for StepGeom_Vector entities. -struct MergeSTEPEntities_VectorHasher -{ - // Hashes the Vector by its name and Vector ratios. - std::size_t operator()(const Handle(StepGeom_Vector)& theVector) const noexcept - { - const size_t aHashes[2]{MergeSTEPEntities_DirectionHasher{}(theVector->Orientation()), - opencascade::hash(static_cast(theVector->Magnitude()))}; - const size_t aCombinedHash = opencascade::hashBytes(aHashes, sizeof(aHashes)); - if (theVector->Name().IsNull()) - { - // If the name is not present, return the hash. - return aCombinedHash; - } - // Add the name to the hash if it is present. - const size_t aCombinedHashWithName[2]{ - aCombinedHash, - std::hash{}(theVector->Name()->String())}; - return opencascade::hashBytes(aCombinedHashWithName, sizeof(aCombinedHashWithName)); - } - - // Compares two Vectors by their names and Vector ratios. - bool operator()(const Handle(StepGeom_Vector)& theVector1, - const Handle(StepGeom_Vector)& theVector2) const noexcept - { - // Compare names. - if (theVector1->Name().IsNull() != theVector2->Name().IsNull()) - { - return false; - } - if (!theVector1->Name()->IsSameString(theVector2->Name())) - { - return false; - } - - // Compare magnitudes. - constexpr double aTolerance = 1e-12; - if (fabs(theVector1->Magnitude() - theVector2->Magnitude()) > aTolerance) - { - return false; - } - - // Compare orientations. - return MergeSTEPEntities_DirectionHasher{}(theVector1->Orientation(), - theVector2->Orientation()); - } -}; - -#endif // _MergeSTEPEntities_VectorHasher_HeaderFile diff --git a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_VectorProcessor.cxx b/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_VectorProcessor.cxx deleted file mode 100644 index 3eb340a91e..0000000000 --- a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_VectorProcessor.cxx +++ /dev/null @@ -1,55 +0,0 @@ -// 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. - -// 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 - -//================================================================================================== - -MergeSTEPEntities_VectorProcessor::MergeSTEPEntities_VectorProcessor( - const Handle(XSControl_WorkSession)& theWS) - : MergeSTEPEntities_EntityProcessor(theWS) -{ - registerReplacer(STANDARD_TYPE(StepGeom_Line), replaceLine); -} - -//================================================================================================== - -bool MergeSTEPEntities_VectorProcessor::replaceLine(const Handle(StepGeom_Vector)& theOldEntity, - const Handle(StepGeom_Vector)& theNewEntity, - Handle(Standard_Transient) theSharing) -{ - Handle(StepGeom_Line) aLine = Handle(StepGeom_Line)::DownCast(theSharing); - if (aLine->Dir() == theOldEntity) - { - aLine->SetDir(theNewEntity); - return true; - } - return false; -} diff --git a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_VectorProcessor.hxx b/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_VectorProcessor.hxx deleted file mode 100644 index 56d198665e..0000000000 --- a/src/DataExchange/TKDESTEP/MergeSTEPEntities/MergeSTEPEntities_VectorProcessor.hxx +++ /dev/null @@ -1,43 +0,0 @@ -// 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. - -#ifndef _MergeSTEPEntities_VectorProcessor_HeaderFile -#define _MergeSTEPEntities_VectorProcessor_HeaderFile - -#include -#include - -#include - -//! Processor for merging StepGeom_Vector entities. -//! This processor merges vectors with the same orientation and magnitude and names. -class MergeSTEPEntities_VectorProcessor - : public MergeSTEPEntities_EntityProcessor -{ -public: - //! Constructor. Stores the work session and registers replacer functions. - //! @param theWS the work session. - Standard_EXPORT MergeSTEPEntities_VectorProcessor(const Handle(XSControl_WorkSession)& theWS); - -private: - //! Replaces the old vector with the new one in the StepGeom_Line entity. - //! @param theOldEntity the old vector. - //! @param theNewEntity the new vector to replace the old one. - //! @param theSharing the StepGeom_Line entity to update. - //! @return true if the vector was replaced, false otherwise. - static bool replaceLine(const Handle(StepGeom_Vector)& theOldEntity, - const Handle(StepGeom_Vector)& theNewEntity, - Handle(Standard_Transient) theSharing); -}; - -#endif // _MergeSTEPEntities_VectorProcessor_HeaderFile diff --git a/src/DataExchange/TKDESTEP/PACKAGES.cmake b/src/DataExchange/TKDESTEP/PACKAGES.cmake index 356c180fb5..6b3443ecc1 100644 --- a/src/DataExchange/TKDESTEP/PACKAGES.cmake +++ b/src/DataExchange/TKDESTEP/PACKAGES.cmake @@ -41,5 +41,5 @@ set(OCCT_TKDESTEP_LIST_OF_PACKAGES APIHeaderSection HeaderSection DESTEP - MergeSTEPEntities + StepTidy ) diff --git a/src/DataExchange/TKDESTEP/RWStepGeom/RWStepGeom_RWBSplineCurveWithKnots.cxx b/src/DataExchange/TKDESTEP/RWStepGeom/RWStepGeom_RWBSplineCurveWithKnots.cxx index ede2a3d994..7db8774702 100644 --- a/src/DataExchange/TKDESTEP/RWStepGeom/RWStepGeom_RWBSplineCurveWithKnots.cxx +++ b/src/DataExchange/TKDESTEP/RWStepGeom/RWStepGeom_RWBSplineCurveWithKnots.cxx @@ -312,6 +312,12 @@ void RWStepGeom_RWBSplineCurveWithKnots::Check(const Handle(StepGeom_BSplineCurv { ach->AddFail("ERROR: No.of KnotMultiplicities not equal No.of Knots"); } + if (nbMult == 0) + { + ach->AddFail("ERROR: No.of KnotMultiplicities is equal to 0"); + return; + } + Standard_Integer i; // svv Jan 10 2000: porting on DEC for (i = 1; i <= nbMult - 1; i++) { diff --git a/src/DataExchange/TKDESTEP/StepTidy/FILES.cmake b/src/DataExchange/TKDESTEP/StepTidy/FILES.cmake new file mode 100644 index 0000000000..c5447aa60c --- /dev/null +++ b/src/DataExchange/TKDESTEP/StepTidy/FILES.cmake @@ -0,0 +1,30 @@ +# Source files for StepTidy package +set(OCCT_StepTidy_FILES_LOCATION "${CMAKE_CURRENT_LIST_DIR}") + +set(OCCT_StepTidy_FILES + StepTidy_Axis2Placement2dHasher.pxx + StepTidy_Axis2Placement3dHasher.pxx + StepTidy_Axis2Placement3dReducer.cxx + StepTidy_Axis2Placement3dReducer.pxx + StepTidy_CartesianPointHasher.pxx + StepTidy_CartesianPointReducer.cxx + StepTidy_CartesianPointReducer.pxx + StepTidy_CircleHasher.pxx + StepTidy_CircleReducer.cxx + StepTidy_CircleReducer.pxx + StepTidy_DirectionHasher.pxx + StepTidy_DirectionReducer.cxx + StepTidy_DirectionReducer.pxx + StepTidy_EntityReducer.pxx + StepTidy_LineHasher.pxx + StepTidy_LineReducer.cxx + StepTidy_LineReducer.pxx + StepTidy_DuplicateCleaner.cxx + StepTidy_DuplicateCleaner.hxx + StepTidy_PlaneHasher.pxx + StepTidy_PlaneReducer.cxx + StepTidy_PlaneReducer.pxx + StepTidy_VectorHasher.pxx + StepTidy_VectorReducer.cxx + StepTidy_VectorReducer.pxx +) diff --git a/src/DataExchange/TKDESTEP/StepTidy/StepTidy_Axis2Placement2dHasher.pxx b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_Axis2Placement2dHasher.pxx new file mode 100644 index 0000000000..89420b2ec2 --- /dev/null +++ b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_Axis2Placement2dHasher.pxx @@ -0,0 +1,80 @@ +// 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. + +#ifndef _StepTidy_Axis2Placement2dHasher_HeaderFile +#define _StepTidy_Axis2Placement2dHasher_HeaderFile + +#include +#include + +#include +#include + +//! OCCT-style hasher for StepGeom_Axis2Placement2d entities. +//! Currently only used for implementation of hasher for StepGeom_Circle. +struct StepTidy_Axis2Placement2dHasher +{ + // Hashes the axis placements. + std::size_t operator()(const Handle(StepGeom_Axis2Placement2d)& thePlacement) const noexcept + { + // Prepare an array of hashes for the location, axis, and ref direction. + // Optimal seed is used for the axis and ref direction if they are not present. + const size_t aHashes[2]{StepTidy_CartesianPointHasher{}(thePlacement->Location()), + thePlacement->HasRefDirection() + ? StepTidy_DirectionHasher{}(thePlacement->RefDirection()) + : opencascade::MurmurHash::optimalSeed()}; + const size_t aHash = opencascade::hashBytes(aHashes, sizeof(aHashes)); + if (thePlacement->Name().IsNull()) + { + // If the name is not present, return the hash. + return aHash; + } + // Add the name to the hash if it is present. + const size_t aHashWithName[2]{ + aHash, + std::hash{}(thePlacement->Name()->String())}; + return opencascade::hashBytes(aHashWithName, sizeof(aHashWithName)); + } + + // Compares two axis placements. + bool operator()(const Handle(StepGeom_Axis2Placement2d)& thePlacement1, + const Handle(StepGeom_Axis2Placement2d)& thePlacement2) const noexcept + { + // Compare names. + if (thePlacement1->Name().IsNull() != thePlacement2->Name().IsNull()) + { + return false; + } + if (!thePlacement1->Name()->IsSameString(thePlacement2->Name())) + { + return false; + } + + // Compare location, axis, and ref direction. + const bool isSameLocation = + StepTidy_CartesianPointHasher{}(thePlacement1->Location(), thePlacement2->Location()); + // Have to check if the axis is present and compare it. + // Have to check if the ref direction is present and compare it. + const bool isSameRefDirectionFlag = + thePlacement1->HasRefDirection() == thePlacement2->HasRefDirection(); + const bool isSameRefDirection = + isSameRefDirectionFlag + && (!thePlacement1->HasRefDirection() + || StepTidy_DirectionHasher{}(thePlacement1->RefDirection(), + thePlacement2->RefDirection())); + + return isSameLocation && isSameRefDirection; + } +}; + +#endif // _StepTidy_Axis2Placement2dHasher_HeaderFile diff --git a/src/DataExchange/TKDESTEP/StepTidy/StepTidy_Axis2Placement3dHasher.pxx b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_Axis2Placement3dHasher.pxx new file mode 100644 index 0000000000..c3600f0958 --- /dev/null +++ b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_Axis2Placement3dHasher.pxx @@ -0,0 +1,86 @@ +// 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. + +#ifndef _StepTidy_Axis2Placement3dHasher_HeaderFile +#define _StepTidy_Axis2Placement3dHasher_HeaderFile + +#include +#include + +#include +#include + +//! OCCT-style hasher for StepGeom_Axis2Placement3d entities. +struct StepTidy_Axis2Placement3dHasher +{ + // Hashes the axis placements. + std::size_t operator()(const Handle(StepGeom_Axis2Placement3d)& thePlacement) const noexcept + { + // Prepare an array of hashes for the location, axis, and ref direction. + // Optimal seed is used for the axis and ref direction if they are not present. + const size_t aHashes[3]{ + StepTidy_CartesianPointHasher{}(thePlacement->Location()), + thePlacement->HasAxis() ? StepTidy_DirectionHasher{}(thePlacement->Axis()) + : opencascade::MurmurHash::optimalSeed(), + thePlacement->HasRefDirection() ? StepTidy_DirectionHasher{}(thePlacement->RefDirection()) + : opencascade::MurmurHash::optimalSeed()}; + const size_t aHash = opencascade::hashBytes(aHashes, sizeof(aHashes)); + if (thePlacement->Name().IsNull()) + { + // If the name is not present, return the hash. + return aHash; + } + // Add the name to the hash if it is present. + const size_t aHashWithName[2]{ + aHash, + std::hash{}(thePlacement->Name()->String())}; + return opencascade::hashBytes(aHashWithName, sizeof(aHashWithName)); + } + + // Compares two axis placements. + bool operator()(const Handle(StepGeom_Axis2Placement3d)& thePlacement1, + const Handle(StepGeom_Axis2Placement3d)& thePlacement2) const noexcept + { + // Compare names. + if (thePlacement1->Name().IsNull() != thePlacement2->Name().IsNull()) + { + return false; + } + if (!thePlacement1->Name()->IsSameString(thePlacement2->Name())) + { + return false; + } + + // Compare location, axis, and ref direction. + const bool isSameLocation = + StepTidy_CartesianPointHasher{}(thePlacement1->Location(), thePlacement2->Location()); + // Have to check if the axis is present and compare it. + const bool isSameAxisFlag = thePlacement1->HasAxis() == thePlacement2->HasAxis(); + const bool isSameAxis = + isSameAxisFlag + && (!thePlacement1->HasAxis() + || StepTidy_DirectionHasher{}(thePlacement1->Axis(), thePlacement2->Axis())); + // Have to check if the ref direction is present and compare it. + const bool isSameRefDirectionFlag = + thePlacement1->HasRefDirection() == thePlacement2->HasRefDirection(); + const bool isSameRefDirection = + isSameRefDirectionFlag + && (!thePlacement1->HasRefDirection() + || StepTidy_DirectionHasher{}(thePlacement1->RefDirection(), + thePlacement2->RefDirection())); + + return isSameLocation && isSameAxis && isSameRefDirection; + } +}; + +#endif // _StepTidy_Axis2Placement3dHasher_HeaderFile diff --git a/src/DataExchange/TKDESTEP/StepTidy/StepTidy_Axis2Placement3dReducer.cxx b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_Axis2Placement3dReducer.cxx new file mode 100644 index 0000000000..57c1389ed9 --- /dev/null +++ b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_Axis2Placement3dReducer.cxx @@ -0,0 +1,298 @@ +// 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 + +//================================================================================================== + +StepTidy_Axis2Placement3dReducer::StepTidy_Axis2Placement3dReducer( + const Handle(XSControl_WorkSession)& theWS) + : StepTidy_EntityReducer(theWS) +{ + registerReplacer(STANDARD_TYPE(StepGeom_Plane), replacePlane); + registerReplacer(STANDARD_TYPE(StepRepr_ItemDefinedTransformation), + replaceItemDefinedTransformation); + registerReplacer(STANDARD_TYPE(StepGeom_CylindricalSurface), replaceCylindricalSurface); + registerReplacer(STANDARD_TYPE(StepShape_ShapeRepresentation), replaceShapeRepresentation); + registerReplacer(STANDARD_TYPE(StepRepr_ConstructiveGeometryRepresentation), + replaceConstructiveGeometryRepresentation); + registerReplacer(STANDARD_TYPE(StepGeom_Circle), replaceCircle); + registerReplacer(STANDARD_TYPE(StepVisual_PresentationLayerAssignment), + replacePresentationLayerAssignment); + registerReplacer(STANDARD_TYPE(StepVisual_StyledItem), replaceStyledItem); + registerReplacer(STANDARD_TYPE(StepGeom_Ellipse), replaceEllipse); + registerReplacer(STANDARD_TYPE(StepGeom_ConicalSurface), replaceConicalSurface); + registerReplacer(STANDARD_TYPE(StepGeom_ToroidalSurface), replaceToroidalSurface); + registerReplacer(STANDARD_TYPE(StepShape_AdvancedBrepShapeRepresentation), + replaceAdvancedBrepShapeRepresentation); + registerReplacer(STANDARD_TYPE(StepGeom_SphericalSurface), replaceSphericalSurface); +} + +//================================================================================================== + +bool StepTidy_Axis2Placement3dReducer::replacePlane( + const Handle(StepGeom_Axis2Placement3d)& theOldEntity, + const Handle(StepGeom_Axis2Placement3d)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepGeom_Plane) aSharing = Handle(StepGeom_Plane)::DownCast(theSharing); + if (aSharing->Position() == theOldEntity) + { + aSharing->SetPosition(theNewEntity); + return true; + } + return false; +} + +//================================================================================================== + +bool StepTidy_Axis2Placement3dReducer::replaceItemDefinedTransformation( + const Handle(StepGeom_Axis2Placement3d)& theOldEntity, + const Handle(StepGeom_Axis2Placement3d)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepRepr_ItemDefinedTransformation) aSharing = + Handle(StepRepr_ItemDefinedTransformation)::DownCast(theSharing); + bool isReplaced = false; + if (aSharing->TransformItem1() == theOldEntity) + { + aSharing->SetTransformItem1(theNewEntity); + isReplaced = true; + } + if (aSharing->TransformItem2() == theOldEntity) + { + aSharing->SetTransformItem2(theNewEntity); + isReplaced = true; + } + return isReplaced; +} + +//================================================================================================== + +bool StepTidy_Axis2Placement3dReducer::replaceCylindricalSurface( + const Handle(StepGeom_Axis2Placement3d)& theOldEntity, + const Handle(StepGeom_Axis2Placement3d)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepGeom_CylindricalSurface) aSharing = + Handle(StepGeom_CylindricalSurface)::DownCast(theSharing); + if (aSharing->Position() == theOldEntity) + { + aSharing->SetPosition(theNewEntity); + return true; + } + return false; +} + +//================================================================================================== + +bool StepTidy_Axis2Placement3dReducer::replaceShapeRepresentation( + const Handle(StepGeom_Axis2Placement3d)& theOldEntity, + const Handle(StepGeom_Axis2Placement3d)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepShape_ShapeRepresentation) aSharing = + Handle(StepShape_ShapeRepresentation)::DownCast(theSharing); + bool isReplaced = false; + for (Standard_Integer anIndex = aSharing->Items()->Lower(); anIndex <= aSharing->Items()->Upper(); + ++anIndex) + { + if (aSharing->Items()->Value(anIndex) == theOldEntity) + { + aSharing->Items()->SetValue(anIndex, theNewEntity); + isReplaced = true; + } + } + return isReplaced; +} + +//================================================================================================== + +bool StepTidy_Axis2Placement3dReducer::replaceConstructiveGeometryRepresentation( + const Handle(StepGeom_Axis2Placement3d)& theOldEntity, + const Handle(StepGeom_Axis2Placement3d)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepRepr_ConstructiveGeometryRepresentation) aSharing = + Handle(StepRepr_ConstructiveGeometryRepresentation)::DownCast(theSharing); + bool isReplaced = false; + for (Standard_Integer anIndex = aSharing->Items()->Lower(); anIndex <= aSharing->Items()->Upper(); + ++anIndex) + { + if (aSharing->Items()->Value(anIndex) == theOldEntity) + { + aSharing->Items()->SetValue(anIndex, theNewEntity); + isReplaced = true; + } + } + return isReplaced; +} + +//================================================================================================== + +bool StepTidy_Axis2Placement3dReducer::replaceCircle( + const Handle(StepGeom_Axis2Placement3d)& theOldEntity, + const Handle(StepGeom_Axis2Placement3d)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepGeom_Circle) aSharing = Handle(StepGeom_Circle)::DownCast(theSharing); + StepGeom_Axis2Placement aSelector = aSharing->Position(); + if (aSelector.Axis2Placement3d() == theOldEntity) + { + aSelector.SetValue(theNewEntity); + return true; + } + return false; +} + +//================================================================================================== + +bool StepTidy_Axis2Placement3dReducer::replacePresentationLayerAssignment( + const Handle(StepGeom_Axis2Placement3d)& theOldEntity, + const Handle(StepGeom_Axis2Placement3d)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepVisual_PresentationLayerAssignment) aSharing = + Handle(StepVisual_PresentationLayerAssignment)::DownCast(theSharing); + bool isReplaced = false; + Handle(StepVisual_HArray1OfLayeredItem) anItems = aSharing->AssignedItems(); + for (Standard_Integer anIndex = anItems->Lower(); anIndex <= anItems->Upper(); ++anIndex) + { + StepVisual_LayeredItem& aLayeredItem = anItems->ChangeValue(anIndex); + if (aLayeredItem.RepresentationItem() == theOldEntity) + { + aLayeredItem.SetValue(theNewEntity); + isReplaced = true; + } + } + return isReplaced; +} + +//================================================================================================== + +bool StepTidy_Axis2Placement3dReducer::replaceStyledItem( + const Handle(StepGeom_Axis2Placement3d)& theOldEntity, + const Handle(StepGeom_Axis2Placement3d)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepVisual_StyledItem) aSharing = Handle(StepVisual_StyledItem)::DownCast(theSharing); + if (aSharing->Item() == theOldEntity) + { + aSharing->SetItem(theNewEntity); + return true; + } + return false; +} + +//================================================================================================== + +bool StepTidy_Axis2Placement3dReducer::replaceEllipse( + const Handle(StepGeom_Axis2Placement3d)& theOldEntity, + const Handle(StepGeom_Axis2Placement3d)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepGeom_Ellipse) aSharing = Handle(StepGeom_Ellipse)::DownCast(theSharing); + StepGeom_Axis2Placement aSelector = aSharing->Position(); + if (aSelector.Axis2Placement3d() == theOldEntity) + { + aSelector.SetValue(theNewEntity); + return true; + } + return false; +} + +//================================================================================================== + +bool StepTidy_Axis2Placement3dReducer::replaceConicalSurface( + const Handle(StepGeom_Axis2Placement3d)& theOldEntity, + const Handle(StepGeom_Axis2Placement3d)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepGeom_ConicalSurface) aSharing = Handle(StepGeom_ConicalSurface)::DownCast(theSharing); + if (aSharing->Position() == theOldEntity) + { + aSharing->SetPosition(theNewEntity); + return true; + } + return false; +} + +//================================================================================================== + +bool StepTidy_Axis2Placement3dReducer::replaceToroidalSurface( + const Handle(StepGeom_Axis2Placement3d)& theOldEntity, + const Handle(StepGeom_Axis2Placement3d)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepGeom_ToroidalSurface) aSharing = + Handle(StepGeom_ToroidalSurface)::DownCast(theSharing); + if (aSharing->Position() == theOldEntity) + { + aSharing->SetPosition(theNewEntity); + return true; + } + return false; +} + +//================================================================================================== + +bool StepTidy_Axis2Placement3dReducer::replaceAdvancedBrepShapeRepresentation( + const Handle(StepGeom_Axis2Placement3d)& theOldEntity, + const Handle(StepGeom_Axis2Placement3d)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepShape_AdvancedBrepShapeRepresentation) aSharing = + Handle(StepShape_AdvancedBrepShapeRepresentation)::DownCast(theSharing); + bool isReplaced = false; + for (Standard_Integer anIndex = aSharing->Items()->Lower(); anIndex <= aSharing->Items()->Upper(); + ++anIndex) + { + if (aSharing->Items()->Value(anIndex) == theOldEntity) + { + aSharing->Items()->SetValue(anIndex, theNewEntity); + isReplaced = true; + } + } + return isReplaced; +} + +//================================================================================================== + +bool StepTidy_Axis2Placement3dReducer::replaceSphericalSurface( + const Handle(StepGeom_Axis2Placement3d)& theOldEntity, + const Handle(StepGeom_Axis2Placement3d)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepGeom_SphericalSurface) aSharing = + Handle(StepGeom_SphericalSurface)::DownCast(theSharing); + if (aSharing->Position() == theOldEntity) + { + aSharing->SetPosition(theNewEntity); + return true; + } + return false; +} diff --git a/src/DataExchange/TKDESTEP/StepTidy/StepTidy_Axis2Placement3dReducer.pxx b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_Axis2Placement3dReducer.pxx new file mode 100644 index 0000000000..7cd8dadd39 --- /dev/null +++ b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_Axis2Placement3dReducer.pxx @@ -0,0 +1,158 @@ +// 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. + +#ifndef _StepTidy_Axis2Placement3dReducer_HeaderFile +#define _StepTidy_Axis2Placement3dReducer_HeaderFile + +#include +#include + +#include + +//! Processor for merging StepGeom_Axis2Placement3d entities. +//! This processor merges axis placements with the same location, axis, and ref direction. +class StepTidy_Axis2Placement3dReducer + : public StepTidy_EntityReducer +{ +public: + //! Constructor. Stores the work session and registers replacer functions. + //! @param theWS the work session. + Standard_EXPORT StepTidy_Axis2Placement3dReducer(const Handle(XSControl_WorkSession)& theWS); + +private: + //! Replaces the old axis placement with the new one in the StepGeom_Plane entity. + //! @param theOldEntity the old axis placement. + //! @param theNewEntity the new axis placement to replace the old one. + //! @param theSharing the StepGeom_Plane entity to update. + //! @return true if the axis placement was replaced, false otherwise. + static bool replacePlane(const Handle(StepGeom_Axis2Placement3d)& theOldEntity, + const Handle(StepGeom_Axis2Placement3d)& theNewEntity, + Handle(Standard_Transient) theSharing); + + //! Replaces the old axis placement with the new one in the StepRepr_ItemDefinedTransformation + //! entity. + //! @param theOldEntity the old axis placement. + //! @param theNewEntity the new axis placement to replace the old one. + //! @param theSharing the StepRepr_ItemDefinedTransformation entity to update. + //! @return true if the axis placement was replaced, false otherwise. + static bool replaceItemDefinedTransformation( + const Handle(StepGeom_Axis2Placement3d)& theOldEntity, + const Handle(StepGeom_Axis2Placement3d)& theNewEntity, + Handle(Standard_Transient) theSharing); + + //! Replaces the old axis placement with the new one in the StepGeom_CylindricalSurface entity. + //! @param theOldEntity the old axis placement. + //! @param theNewEntity the new axis placement to replace the old one. + //! @param theSharing the StepGeom_CylindricalSurface entity to update. + //! @return true if the axis placement was replaced, false otherwise. + static bool replaceCylindricalSurface(const Handle(StepGeom_Axis2Placement3d)& theOldEntity, + const Handle(StepGeom_Axis2Placement3d)& theNewEntity, + Handle(Standard_Transient) theSharing); + + //! Replaces the old axis placement with the new one in the StepShape_ShapeRepresentation entity. + //! @param theOldEntity the old axis placement. + //! @param theNewEntity the new axis placement to replace the old one. + //! @param theSharing the StepShape_ShapeRepresentation entity to update. + //! @return true if the axis placement was replaced, false otherwise. + static bool replaceShapeRepresentation(const Handle(StepGeom_Axis2Placement3d)& theOldEntity, + const Handle(StepGeom_Axis2Placement3d)& theNewEntity, + Handle(Standard_Transient) theSharing); + + //! Replaces the old axis placement with the new one in the + //! StepRepr_ConstructiveGeometryRepresentation entity. + //! @param theOldEntity the old axis placement. + //! @param theNewEntity the new axis placement to replace the old one. + //! @param theSharing the StepRepr_ConstructiveGeometryRepresentation entity to update. + //! @return true if the axis placement was replaced, false otherwise. + static bool replaceConstructiveGeometryRepresentation( + const Handle(StepGeom_Axis2Placement3d)& theOldEntity, + const Handle(StepGeom_Axis2Placement3d)& theNewEntity, + Handle(Standard_Transient) theSharing); + + //! Replaces the old axis placement with the new one in the StepGeom_Circle entity. + //! @param theOldEntity the old axis placement. + //! @param theNewEntity the new axis placement to replace the old one. + //! @param theSharing the StepGeom_Circle entity to update. + //! @return true if the axis placement was replaced, false otherwise. + static bool replaceCircle(const Handle(StepGeom_Axis2Placement3d)& theOldEntity, + const Handle(StepGeom_Axis2Placement3d)& theNewEntity, + Handle(Standard_Transient) theSharing); + + //! Replaces the old axis placement with the new one in the StepGeom_PresentationLayerAssignment + //! @param theOldEntity the old axis placement. + //! @param theNewEntity the new axis placement to replace the old one. + //! @param theSharing the StepGeom_PresentationLayerAssignment entity to update. + //! @return true if the axis placement was replaced, false otherwise. + static bool replacePresentationLayerAssignment( + const Handle(StepGeom_Axis2Placement3d)& theOldEntity, + const Handle(StepGeom_Axis2Placement3d)& theNewEntity, + Handle(Standard_Transient) theSharing); + + //! Replaces the old axis placement with the new one in the StepVisual_StyledItem entity. + //! @param theOldEntity the old axis placement. + //! @param theNewEntity the new axis placement to replace the old one. + //! @param theSharing the StepVisual_StyledItem entity to update. + //! @return true if the axis placement was replaced, false otherwise. + static bool replaceStyledItem(const Handle(StepGeom_Axis2Placement3d)& theOldEntity, + const Handle(StepGeom_Axis2Placement3d)& theNewEntity, + Handle(Standard_Transient) theSharing); + + //! Replaces the old axis placement with the new one in the StepGeom_Ellipse entity. + //! @param theOldEntity the old axis placement. + //! @param theNewEntity the new axis placement to replace the old one. + //! @param theSharing the StepGeom_Ellipse entity to update. + //! @return true if the axis placement was replaced, false otherwise. + static bool replaceEllipse(const Handle(StepGeom_Axis2Placement3d)& theOldEntity, + const Handle(StepGeom_Axis2Placement3d)& theNewEntity, + Handle(Standard_Transient) theSharing); + + //! Replaces the old axis placement with the new one in the StepGeom_ConicalSurface entity. + //! @param theOldEntity the old axis placement. + //! @param theNewEntity the new axis placement to replace the old one. + //! @param theSharing the StepGeom_ConicalSurface entity to update. + //! @return true if the axis placement was replaced, false otherwise. + static bool replaceConicalSurface(const Handle(StepGeom_Axis2Placement3d)& theOldEntity, + const Handle(StepGeom_Axis2Placement3d)& theNewEntity, + Handle(Standard_Transient) theSharing); + + //! Replaces the old axis placement with the new one in the StepGeom_ToroidalSurface entity. + //! @param theOldEntity the old axis placement. + //! @param theNewEntity the new axis placement to replace the old one. + //! @param theSharing the StepGeom_ToroidalSurface entity to update. + //! @return true if the axis placement was replaced, false otherwise. + static bool replaceToroidalSurface(const Handle(StepGeom_Axis2Placement3d)& theOldEntity, + const Handle(StepGeom_Axis2Placement3d)& theNewEntity, + Handle(Standard_Transient) theSharing); + + //! Replaces the old axis placement with the new one in the + //! StepShape_AdvancedBrepShapeRepresentation entity. + //! @param theOldEntity the old axis placement. + //! @param theNewEntity the new axis placement to replace the old one. + //! @param theSharing the StepShape_AdvancedBrepShapeRepresentation entity to update. + //! @return true if the axis placement was replaced, false otherwise. + static bool replaceAdvancedBrepShapeRepresentation( + const Handle(StepGeom_Axis2Placement3d)& theOldEntity, + const Handle(StepGeom_Axis2Placement3d)& theNewEntity, + Handle(Standard_Transient) theSharing); + + //! Replaces the old axis placement with the new one in the StepGeom_SphericalSurface entity. + //! @param theOldEntity the old axis placement. + //! @param theNewEntity the new axis placement to replace the old one. + //! @param theSharing the StepGeom_SphericalSurface entity to update. + //! @return true if the axis placement was replaced, false otherwise. + static bool replaceSphericalSurface(const Handle(StepGeom_Axis2Placement3d)& theOldEntity, + const Handle(StepGeom_Axis2Placement3d)& theNewEntity, + Handle(Standard_Transient) theSharing); +}; + +#endif // _StepTidy_DirectionReducer_HeaderFile diff --git a/src/DataExchange/TKDESTEP/StepTidy/StepTidy_CartesianPointHasher.pxx b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_CartesianPointHasher.pxx new file mode 100644 index 0000000000..61591d50d8 --- /dev/null +++ b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_CartesianPointHasher.pxx @@ -0,0 +1,74 @@ +// 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. + +#ifndef _StepTidy_CartesianPointHasher_HeaderFile +#define _StepTidy_CartesianPointHasher_HeaderFile + +#include +#include +#include + +//! OCCT-style hasher for StepGeom_CartesianPoint entities. +struct StepTidy_CartesianPointHasher +{ + // Hashes the Cartesian point by its name and coordinates. + std::size_t operator()(const Handle(StepGeom_CartesianPoint)& theCartesianPoint) const noexcept + { + const std::array& aCoords = theCartesianPoint->Coordinates(); + // If Cartesian point has no name, hash only coordinates. + if (theCartesianPoint->Name().IsNull()) + { + return opencascade::hashBytes(aCoords.data(), static_cast(aCoords.size())); + } + // Otherwise, hash both coordinates and name. + const size_t aHashes[2]{ + opencascade::hashBytes(aCoords.data(), static_cast(aCoords.size())), + std::hash{}(theCartesianPoint->Name()->String())}; + + return opencascade::hashBytes(aHashes, sizeof(aHashes)); + } + + // Compares two Cartesian points by their names and coordinates. + bool operator()(const Handle(StepGeom_CartesianPoint)& theCartesianPoint1, + const Handle(StepGeom_CartesianPoint)& theCartesianPoint2) const noexcept + { + // Compare names. + if (theCartesianPoint1->Name().IsNull() != theCartesianPoint2->Name().IsNull()) + { + return false; + } + if (!theCartesianPoint1->Name()->IsSameString(theCartesianPoint2->Name())) + { + return false; + } + + // Compare coordinates. + constexpr double aTolerance = 1e-12; + const std::array& aCoords1 = theCartesianPoint1->Coordinates(); + const std::array& aCoords2 = theCartesianPoint2->Coordinates(); + if (aCoords1.size() != aCoords2.size()) + { + return false; + } + for (size_t anIndex = 0; anIndex < aCoords1.size(); ++anIndex) + { + if (std::abs(aCoords1[anIndex] - aCoords2[anIndex]) > aTolerance) + { + return false; + } + } + return true; + } +}; + +#endif // _StepTidy_CartesianPointHasher_HeaderFile diff --git a/src/DataExchange/TKDESTEP/StepTidy/StepTidy_CartesianPointReducer.cxx b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_CartesianPointReducer.cxx new file mode 100644 index 0000000000..144ff60ebb --- /dev/null +++ b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_CartesianPointReducer.cxx @@ -0,0 +1,301 @@ +// 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 + +//================================================================================================== + +StepTidy_CartesianPointReducer::StepTidy_CartesianPointReducer( + const Handle(XSControl_WorkSession)& theWS) + : StepTidy_EntityReducer(theWS) +{ + registerReplacer(STANDARD_TYPE(StepGeom_Axis1Placement), replaceAxis1Placement); + registerReplacer(STANDARD_TYPE(StepGeom_Axis2Placement3d), replaceAxis2Placement3d); + registerReplacer(STANDARD_TYPE(StepShape_VertexPoint), replaceVertexPoint); + registerReplacer(STANDARD_TYPE(StepShape_GeometricCurveSet), replaceGeometricCurveSet); + registerReplacer(STANDARD_TYPE(StepVisual_PresentationLayerAssignment), + replacePresentationLayerAssignment); + registerReplacer(STANDARD_TYPE(StepVisual_StyledItem), replaceStyledItem); + registerReplacer(STANDARD_TYPE(StepGeom_BSplineCurveWithKnots), replaceBSplineCurveWithKnots); + registerReplacer(STANDARD_TYPE(StepGeom_Line), replaceLine); + registerReplacer(STANDARD_TYPE(StepGeom_BSplineSurfaceWithKnots), replaceBSplineSurfaceWithKnots); + registerReplacer(STANDARD_TYPE(StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve), + replaceBSplineCurveWithKnotsAndRationalBSplineCurve); + registerReplacer(STANDARD_TYPE(StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface), + replaceBSplineSurfaceWithKnotsAndRationalBSplineSurface); + registerReplacer(STANDARD_TYPE(StepRepr_Representation), replaceRepresentation); +} + +//================================================================================================== + +bool StepTidy_CartesianPointReducer::replaceAxis2Placement3d( + const Handle(StepGeom_CartesianPoint)& theOldEntity, + const Handle(StepGeom_CartesianPoint)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepGeom_Axis2Placement3d) aSharing = + Handle(StepGeom_Axis2Placement3d)::DownCast(theSharing); + if (aSharing->Location() == theOldEntity) + { + aSharing->SetLocation(theNewEntity); + return true; + } + return false; +} + +//================================================================================================== + +bool StepTidy_CartesianPointReducer::replaceVertexPoint( + const Handle(StepGeom_CartesianPoint)& theOldEntity, + const Handle(StepGeom_CartesianPoint)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepShape_VertexPoint) aSharing = Handle(StepShape_VertexPoint)::DownCast(theSharing); + if (aSharing->VertexGeometry() == theOldEntity) + { + aSharing->SetVertexGeometry(theNewEntity); + return true; + } + return false; +} + +//================================================================================================== + +bool StepTidy_CartesianPointReducer::replaceGeometricCurveSet( + const Handle(StepGeom_CartesianPoint)& theOldEntity, + const Handle(StepGeom_CartesianPoint)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepShape_GeometricSet) aSharing = Handle(StepShape_GeometricSet)::DownCast(theSharing); + bool isReplaced = false; + for (auto& anElement : *aSharing->Elements()) + { + const Handle(StepGeom_Point) aCurrentPoint = anElement.Point(); + if (aCurrentPoint && aCurrentPoint == theOldEntity) + { + anElement.SetValue(theNewEntity); + isReplaced = true; + } + } + return isReplaced; +} + +//================================================================================================== + +bool StepTidy_CartesianPointReducer::replacePresentationLayerAssignment( + const Handle(StepGeom_CartesianPoint)& theOldEntity, + const Handle(StepGeom_CartesianPoint)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepVisual_PresentationLayerAssignment) aSharing = + Handle(StepVisual_PresentationLayerAssignment)::DownCast(theSharing); + bool isReplaced = false; + for (auto& anAssignedItem : *aSharing->AssignedItems()) + { + const Handle(StepRepr_RepresentationItem) aRepItem = anAssignedItem.RepresentationItem(); + if (aRepItem == theOldEntity) + { + anAssignedItem.SetValue(theNewEntity); + isReplaced = true; + } + } + return isReplaced; +} + +//================================================================================================== + +bool StepTidy_CartesianPointReducer::replaceStyledItem( + const Handle(StepGeom_CartesianPoint)& theOldEntity, + const Handle(StepGeom_CartesianPoint)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepVisual_StyledItem) aSharing = Handle(StepVisual_StyledItem)::DownCast(theSharing); + if (aSharing->Item() == theOldEntity) + { + aSharing->SetItem(theNewEntity); + return true; + } + return false; +} + +//================================================================================================== + +bool StepTidy_CartesianPointReducer::replaceBSplineCurveWithKnots( + const Handle(StepGeom_CartesianPoint)& theOldEntity, + const Handle(StepGeom_CartesianPoint)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepGeom_BSplineCurveWithKnots) aSharing = + Handle(StepGeom_BSplineCurveWithKnots)::DownCast(theSharing); + bool isReplaced = false; + Handle(StepGeom_HArray1OfCartesianPoint) aControlPoints = aSharing->ControlPointsList(); + for (Standard_Integer anIndex = aControlPoints->Lower(); anIndex <= aControlPoints->Upper(); + ++anIndex) + { + if (aControlPoints->Value(anIndex) == theOldEntity) + { + aControlPoints->SetValue(anIndex, theNewEntity); + isReplaced = true; + } + } + return isReplaced; +} + +//================================================================================================== + +bool StepTidy_CartesianPointReducer::replaceLine( + const Handle(StepGeom_CartesianPoint)& theOldEntity, + const Handle(StepGeom_CartesianPoint)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepGeom_Line) aSharing = Handle(StepGeom_Line)::DownCast(theSharing); + if (aSharing->Pnt() == theOldEntity) + { + aSharing->SetPnt(theNewEntity); + return true; + } + return false; +} + +//================================================================================================== + +bool StepTidy_CartesianPointReducer::replaceBSplineSurfaceWithKnots( + const Handle(StepGeom_CartesianPoint)& theOldEntity, + const Handle(StepGeom_CartesianPoint)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepGeom_BSplineSurfaceWithKnots) aSharing = + Handle(StepGeom_BSplineSurfaceWithKnots)::DownCast(theSharing); + bool isReplaced = false; + Handle(StepGeom_HArray2OfCartesianPoint) aControlPoints = aSharing->ControlPointsList(); + for (Standard_Integer anIndexI = aControlPoints->LowerRow(); + anIndexI <= aControlPoints->UpperRow(); + ++anIndexI) + { + for (Standard_Integer anIndexJ = aControlPoints->LowerCol(); + anIndexJ <= aControlPoints->UpperCol(); + ++anIndexJ) + { + if (aControlPoints->Value(anIndexI, anIndexJ) == theOldEntity) + { + aControlPoints->SetValue(anIndexI, anIndexJ, theNewEntity); + isReplaced = true; + } + } + } + return isReplaced; +} + +//================================================================================================== + +bool StepTidy_CartesianPointReducer::replaceAxis1Placement( + const Handle(StepGeom_CartesianPoint)& theOldEntity, + const Handle(StepGeom_CartesianPoint)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepGeom_Axis1Placement) aSharing = Handle(StepGeom_Axis1Placement)::DownCast(theSharing); + if (aSharing->Location() == theOldEntity) + { + aSharing->SetLocation(theNewEntity); + return true; + } + return false; +} + +//================================================================================================== + +bool StepTidy_CartesianPointReducer::replaceRepresentation( + const Handle(StepGeom_CartesianPoint)& theOldEntity, + const Handle(StepGeom_CartesianPoint)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepRepr_Representation) aSharing = Handle(StepRepr_Representation)::DownCast(theSharing); + bool isReplaced = false; + Handle(StepRepr_HArray1OfRepresentationItem) anItems = aSharing->Items(); + for (Standard_Integer anIndex = 1; anIndex <= aSharing->NbItems(); ++anIndex) + { + const Handle(StepRepr_RepresentationItem) aRepItem = anItems->Value(anIndex); + if (aRepItem == theOldEntity) + { + anItems->SetValue(anIndex, theNewEntity); + isReplaced = true; + } + } + return isReplaced; +} + +//================================================================================================== + +bool StepTidy_CartesianPointReducer::replaceBSplineCurveWithKnotsAndRationalBSplineCurve( + const Handle(StepGeom_CartesianPoint)& theOldEntity, + const Handle(StepGeom_CartesianPoint)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve) aSharing = + Handle(StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve)::DownCast(theSharing); + bool isReplaced = false; + Handle(StepGeom_HArray1OfCartesianPoint) aControlPoints = aSharing->ControlPointsList(); + for (Standard_Integer anIndex = aControlPoints->Lower(); anIndex <= aControlPoints->Upper(); + ++anIndex) + { + if (aControlPoints->Value(anIndex) == theOldEntity) + { + aControlPoints->SetValue(anIndex, theNewEntity); + isReplaced = true; + } + } + return isReplaced; +} + +//================================================================================================== + +bool StepTidy_CartesianPointReducer::replaceBSplineSurfaceWithKnotsAndRationalBSplineSurface( + const Handle(StepGeom_CartesianPoint)& theOldEntity, + const Handle(StepGeom_CartesianPoint)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface) aSharing = + Handle(StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface)::DownCast(theSharing); + bool isReplaced = false; + Handle(StepGeom_HArray2OfCartesianPoint) aControlPoints = aSharing->ControlPointsList(); + for (Standard_Integer anIndexI = aControlPoints->LowerRow(); + anIndexI <= aControlPoints->UpperRow(); + ++anIndexI) + { + for (Standard_Integer anIndexJ = aControlPoints->LowerCol(); + anIndexJ <= aControlPoints->UpperCol(); + ++anIndexJ) + { + if (aControlPoints->Value(anIndexI, anIndexJ) == theOldEntity) + { + aControlPoints->SetValue(anIndexI, anIndexJ, theNewEntity); + isReplaced = true; + } + } + } + return isReplaced; +} diff --git a/src/DataExchange/TKDESTEP/StepTidy/StepTidy_CartesianPointReducer.pxx b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_CartesianPointReducer.pxx new file mode 100644 index 0000000000..bc2a6cd384 --- /dev/null +++ b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_CartesianPointReducer.pxx @@ -0,0 +1,161 @@ +// 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. + +#ifndef _StepTidy_CartesianPointReducer_HeaderFile +#define _StepTidy_CartesianPointReducer_HeaderFile + +#include +#include + +#include + +//! Processor for merging StepGeom_CartesianPoint entities. +//! This processor is responsible for merging Cartesian points with the same coordinates and names. +//! It is used to remove duplicate Cartesian points from the STEP model. +//! See StepTidy_EntityReducer for the description of the Reducer workflow. +class StepTidy_CartesianPointReducer + : public StepTidy_EntityReducer +{ +public: + //! Constructor. Accepts a work session containing the model to process. + //! Registers replacer functions for all supported sharing entities. + //! @param theWS Work session. + Standard_EXPORT StepTidy_CartesianPointReducer(const Handle(XSControl_WorkSession)& theWS); + +private: + //! Replaces the old Cartesian point with the new Cartesian point in + //! the sharing StepGeom_Axis2Placement3d. + //! @param theOldEntity Old Cartesian point to replace. + //! @param theNewEntity New Cartesian point to replace the old entity with. + //! @param theSharing The StepGeom_Axis2Placement3d sharing the old entity. + //! @return True if the entity was replaced, false if it was not. + static bool replaceAxis2Placement3d(const Handle(StepGeom_CartesianPoint)& theOldEntity, + const Handle(StepGeom_CartesianPoint)& theNewEntity, + Handle(Standard_Transient) theSharing); + + //! Replaces the old Cartesian point with the new Cartesian point in + //! the sharing StepShape_VertexPoint. + //! @param theOldEntity Old Cartesian point to replace. + //! @param theNewEntity New Cartesian point to replace the old entity with. + //! @param theSharing The StepShape_VertexPoint sharing the old entity. + //! @return True if the entity was replaced, false if it was not. + static bool replaceVertexPoint(const Handle(StepGeom_CartesianPoint)& theOldEntity, + const Handle(StepGeom_CartesianPoint)& theNewEntity, + Handle(Standard_Transient) theSharing); + + //! Replaces the old Cartesian point with the new Cartesian point in + //! the sharing StepShape_GeometricSet. + //! @param theOldEntity Old Cartesian point to replace. + //! @param theNewEntity New Cartesian point to replace the old entity with. + //! @param theSharing The StepShape_GeometricSet sharing the old entity. + //! @return True if the entity was replaced, false if it was not. + static bool replaceGeometricCurveSet(const Handle(StepGeom_CartesianPoint)& theOldEntity, + const Handle(StepGeom_CartesianPoint)& theNewEntity, + Handle(Standard_Transient) theSharing); + + //! Replaces the old Cartesian point with the new Cartesian point in + //! the sharing StepVisual_PresentationLayerAssignment. + //! @param theOldEntity Old Cartesian point to replace. + //! @param theNewEntity New Cartesian point to replace the old entity with. + //! @param theSharing The StepVisual_PresentationLayerAssignment sharing the old entity. + //! @return True if the entity was replaced, false if it was not. + static bool replacePresentationLayerAssignment( + const Handle(StepGeom_CartesianPoint)& theOldEntity, + const Handle(StepGeom_CartesianPoint)& theNewEntity, + Handle(Standard_Transient) theSharing); + + //! Replaces the old Cartesian point with the new Cartesian point in + //! the sharing StepVisual_StyledItem. + //! @param theOldEntity Old Cartesian point to replace. + //! @param theNewEntity New Cartesian point to replace the old entity with. + //! @param theSharing The StepVisual_StyledItem sharing the old entity. + //! @return True if the entity was replaced, false if it was not. + static bool replaceStyledItem(const Handle(StepGeom_CartesianPoint)& theOldEntity, + const Handle(StepGeom_CartesianPoint)& theNewEntity, + Handle(Standard_Transient) theSharing); + + //! Replaces the old Cartesian point with the new Cartesian point in + //! the sharing StepGeom_BSplineCurveWithKnots. + //! @param theOldEntity Old Cartesian point to replace. + //! @param theNewEntity New Cartesian point to replace the old entity with. + //! @param theSharing The StepGeom_BSplineCurveWithKnots sharing the old entity. + //! @return True if the entity was replaced, false if it was not. + static bool replaceBSplineCurveWithKnots(const Handle(StepGeom_CartesianPoint)& theOldEntity, + const Handle(StepGeom_CartesianPoint)& theNewEntity, + Handle(Standard_Transient) theSharing); + + //! Replaces the old Cartesian point with the new Cartesian point in + //! the sharing StepGeom_Line. + //! @param theOldEntity Old Cartesian point to replace. + //! @param theNewEntity New Cartesian point to replace the old entity with. + //! @param theSharing The StepGeom_Line sharing the old entity. + //! @return True if the entity was replaced, false if it was not. + static bool replaceLine(const Handle(StepGeom_CartesianPoint)& theOldEntity, + const Handle(StepGeom_CartesianPoint)& theNewEntity, + Handle(Standard_Transient) theSharing); + + //! Replaces the old Cartesian point with the new Cartesian point in + //! the sharing StepGeom_BSplineSurfaceWithKnots. + //! @param theOldEntity Old Cartesian point to replace. + //! @param theNewEntity New Cartesian point to replace the old entity with. + //! @param theSharing The StepGeom_BSplineSurfaceWithKnots sharing the old entity. + //! @return True if the entity was replaced, false if it was not. + static bool replaceBSplineSurfaceWithKnots(const Handle(StepGeom_CartesianPoint)& theOldEntity, + const Handle(StepGeom_CartesianPoint)& theNewEntity, + Handle(Standard_Transient) theSharing); + + //! Replaces the old Cartesian point with the new Cartesian point in + //! the sharing StepGeom_Axis1Placement. + //! @param theOldEntity Old Cartesian point to replace. + //! @param theNewEntity New Cartesian point to replace the old entity with. + //! @param theSharing The StepGeom_Axis1Placement sharing the old entity. + //! @return True if the entity was replaced, false if it was not. + static bool replaceAxis1Placement(const Handle(StepGeom_CartesianPoint)& theOldEntity, + const Handle(StepGeom_CartesianPoint)& theNewEntity, + Handle(Standard_Transient) theSharing); + + //! Replaces the old Cartesian point with the new Cartesian point in + //! the sharing StepRepr_Representation. + //! @param theOldEntity Old Cartesian point to replace. + //! @param theNewEntity New Cartesian point to replace the old entity with. + //! @param theSharing The StepRepr_Representation sharing the old entity. + //! @return True if the entity was replaced, false if it was not. + static bool replaceRepresentation(const Handle(StepGeom_CartesianPoint)& theOldEntity, + const Handle(StepGeom_CartesianPoint)& theNewEntity, + Handle(Standard_Transient) theSharing); + + //! Replaces the old Cartesian point with the new Cartesian point in + //! the sharing StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve. + //! @param theOldEntity Old Cartesian point to replace. + //! @param theNewEntity New Cartesian point to replace the old entity with. + //! @param theSharing The StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve sharing the old + //! entity. + //! @return True if the entity was replaced, false if it was not. + static bool replaceBSplineCurveWithKnotsAndRationalBSplineCurve( + const Handle(StepGeom_CartesianPoint)& theOldEntity, + const Handle(StepGeom_CartesianPoint)& theNewEntity, + Handle(Standard_Transient) theSharing); + + //! Replaces the old Cartesian point with the new Cartesian point in + //! the sharing StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface. + //! @param theOldEntity Old Cartesian point to replace. + //! @param theNewEntity New Cartesian point to replace the old entity with. + //! @param theSharing The StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface sharing the + //! old entity. + static bool replaceBSplineSurfaceWithKnotsAndRationalBSplineSurface( + const Handle(StepGeom_CartesianPoint)& theOldEntity, + const Handle(StepGeom_CartesianPoint)& theNewEntity, + Handle(Standard_Transient) theSharing); +}; + +#endif // _StepTidy_CartesianPointReducer_HeaderFile diff --git a/src/DataExchange/TKDESTEP/StepTidy/StepTidy_CircleHasher.pxx b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_CircleHasher.pxx new file mode 100644 index 0000000000..ae890b200f --- /dev/null +++ b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_CircleHasher.pxx @@ -0,0 +1,101 @@ +// 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. + +#ifndef _StepTidy_CircleHasher_HeaderFile +#define _StepTidy_CircleHasher_HeaderFile + +#include +#include + +#include +#include +#include + +//! OCCT-style hasher for StepGeom_Circle entities. +struct StepTidy_CircleHasher +{ + //! Returns hash for a Circle entity. + std::size_t operator()(const Handle(StepGeom_Circle)& theCircle) const noexcept + { + const size_t aPositionHash = + !theCircle->Position().Axis2Placement2d().IsNull() + ? StepTidy_Axis2Placement2dHasher{}(theCircle->Position().Axis2Placement2d()) + : !theCircle->Position().Axis2Placement3d().IsNull() + ? StepTidy_Axis2Placement3dHasher{}(theCircle->Position().Axis2Placement3d()) + : opencascade::MurmurHash::optimalSeed(); + + const size_t aRadiusHash = opencascade::hash(static_cast(theCircle->Radius())); + + const size_t aHashes[2]{aPositionHash, aRadiusHash}; + const size_t aCombinedHash = opencascade::hashBytes(aHashes, sizeof(aHashes)); + if (theCircle->Name().IsNull()) + { + // If the name is not present, return the hash. + return aCombinedHash; + } + // Add the name to the hash if it is present. + const size_t aHashWithName[2]{ + aCombinedHash, + std::hash{}(theCircle->Name()->String())}; + return opencascade::hashBytes(aHashWithName, sizeof(aHashWithName)); + } + + //! Compares two Circle entities. + bool operator()(const Handle(StepGeom_Circle)& theCircle1, + const Handle(StepGeom_Circle)& theCircle2) const noexcept + { + // Compare names. + if (theCircle1->Name().IsNull() != theCircle2->Name().IsNull()) + { + return false; + } + if (!theCircle1->Name()->IsSameString(theCircle2->Name())) + { + return false; + } + + // Compare axis placements. + if (theCircle1->Position().CaseNumber() != theCircle2->Position().CaseNumber()) + { + return false; + } + + if (theCircle1->Position().CaseNumber() == 1) + { + if (!StepTidy_Axis2Placement2dHasher{}(theCircle1->Position().Axis2Placement2d(), + theCircle2->Position().Axis2Placement2d())) + { + return false; + } + } + else if (theCircle1->Position().CaseNumber() == 2) + { + if (!StepTidy_Axis2Placement3dHasher{}(theCircle1->Position().Axis2Placement3d(), + theCircle2->Position().Axis2Placement3d())) + { + return false; + } + } + + // Compare radius. + constexpr Standard_Real aTolerance = 1e-12; + if (Abs(theCircle1->Radius() - theCircle2->Radius()) > aTolerance) + { + return false; + } + + return true; + } +}; + +#endif // _StepTidy_CircleHasher_HeaderFile diff --git a/src/DataExchange/TKDESTEP/StepTidy/StepTidy_CircleReducer.cxx b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_CircleReducer.cxx new file mode 100644 index 0000000000..5dbad0700a --- /dev/null +++ b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_CircleReducer.cxx @@ -0,0 +1,74 @@ +// 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 + +//================================================================================================== + +StepTidy_CircleReducer::StepTidy_CircleReducer(const Handle(XSControl_WorkSession)& theWS) + : StepTidy_EntityReducer(theWS) +{ + registerReplacer(STANDARD_TYPE(StepShape_EdgeCurve), replaceEdgeCurve); + registerReplacer(STANDARD_TYPE(StepGeom_SurfaceCurve), replaceSurfaceCurve); + registerReplacer(STANDARD_TYPE(StepGeom_SeamCurve), replaceSeamCurve); +} + +//================================================================================================== + +bool StepTidy_CircleReducer::replaceEdgeCurve(const Handle(StepGeom_Circle)& theOldEntity, + const Handle(StepGeom_Circle)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepShape_EdgeCurve) aSharing = Handle(StepShape_EdgeCurve)::DownCast(theSharing); + if (aSharing->EdgeGeometry() == theOldEntity) + { + aSharing->SetEdgeGeometry(theNewEntity); + return true; + } + return false; +} + +//================================================================================================== + +bool StepTidy_CircleReducer::replaceSurfaceCurve(const Handle(StepGeom_Circle)& theOldEntity, + const Handle(StepGeom_Circle)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepGeom_SurfaceCurve) aSharing = Handle(StepGeom_SurfaceCurve)::DownCast(theSharing); + if (aSharing->Curve3d() == theOldEntity) + { + aSharing->SetCurve3d(theNewEntity); + return true; + } + return false; +} + +//================================================================================================== + +bool StepTidy_CircleReducer::replaceSeamCurve(const Handle(StepGeom_Circle)& theOldEntity, + const Handle(StepGeom_Circle)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepGeom_SeamCurve) aSharing = Handle(StepGeom_SeamCurve)::DownCast(theSharing); + if (aSharing->Curve3d() == theOldEntity) + { + aSharing->SetCurve3d(theNewEntity); + return true; + } + return false; +} diff --git a/src/DataExchange/TKDESTEP/StepTidy/StepTidy_CircleReducer.pxx b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_CircleReducer.pxx new file mode 100644 index 0000000000..479b5d8683 --- /dev/null +++ b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_CircleReducer.pxx @@ -0,0 +1,63 @@ +// 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. + +#ifndef _StepTidy_CircleReducer_HeaderFile +#define _StepTidy_CircleReducer_HeaderFile + +#include +#include + +#include + +//! Processor for merging StepGeom_Circle entities. +//! This processor merges circles with the same position and radius and names. +class StepTidy_CircleReducer : public StepTidy_EntityReducer +{ +public: + //! Constructor. Stores the work session and registers replacer functions. + //! @param theWS the work session. + Standard_EXPORT StepTidy_CircleReducer(const Handle(XSControl_WorkSession)& theWS); + +private: + //! Replacer function for StepShape_EdgeCurve entities. + //! Replaces the old entity with the new one in the sharing entity. + //! @param theOldEntity the old entity to replace. + //! @param theNewEntity the new entity to replace with. + //! @param theSharing the sharing entity in which to replace the old entity. + //! @return true if the entity was replaced, false otherwise. + static bool replaceEdgeCurve(const Handle(StepGeom_Circle)& theOldEntity, + const Handle(StepGeom_Circle)& theNewEntity, + Handle(Standard_Transient) theSharing); + + //! Replacer function for StepGeom_SurfaceCurve entities. + //! Replaces the old entity with the new one in the sharing entity. + //! @param theOldEntity the old entity to replace. + //! @param theNewEntity the new entity to replace with. + //! @param theSharing the sharing entity in which to replace the old entity. + //! @return true if the entity was replaced, false otherwise. + static bool replaceSurfaceCurve(const Handle(StepGeom_Circle)& theOldEntity, + const Handle(StepGeom_Circle)& theNewEntity, + Handle(Standard_Transient) theSharing); + + //! Replacer function for StepGeom_SeamCurve entities. + //! Replaces the old entity with the new one in the sharing entity. + //! @param theOldEntity the old entity to replace. + //! @param theNewEntity the new entity to replace with. + //! @param theSharing the sharing entity in which to replace the old entity. + //! @return true if the entity was replaced, false otherwise. + static bool replaceSeamCurve(const Handle(StepGeom_Circle)& theOldEntity, + const Handle(StepGeom_Circle)& theNewEntity, + Handle(Standard_Transient) theSharing); +}; + +#endif // _StepTidy_CircleReducer_HeaderFile diff --git a/src/DataExchange/TKDESTEP/StepTidy/StepTidy_DirectionHasher.pxx b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_DirectionHasher.pxx new file mode 100644 index 0000000000..3ef985ff25 --- /dev/null +++ b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_DirectionHasher.pxx @@ -0,0 +1,78 @@ +// 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. + +#ifndef _StepTidy_DirectionHasher_HeaderFile +#define _StepTidy_DirectionHasher_HeaderFile + +#include +#include +#include + +//! OCCT-style hasher for StepGeom_Direction entities. +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(aCoords->Value(anIndex)); + } + // If direction has no name, hash only direction ratios. + if (theDirection->Name().IsNull()) + { + return opencascade::hashBytes(anArray, sizeof(anArray)); + } + // Otherwise, hash both direction ratios and name. + const size_t aHashes[2]{opencascade::hashBytes(anArray, sizeof(anArray)), + std::hash{}(theDirection->Name()->String())}; + return opencascade::hashBytes(aHashes, sizeof(aHashes)); + } + + // Compares two directions by their names and direction ratios. + bool operator()(const Handle(StepGeom_Direction)& theDirection1, + const Handle(StepGeom_Direction)& theDirection2) const noexcept + { + // Compare names. + if (theDirection1->Name().IsNull() != theDirection2->Name().IsNull()) + { + return false; + } + if (!theDirection1->Name()->IsSameString(theDirection2->Name())) + { + return false; + } + + // 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()) + { + return false; + } + for (Standard_Integer i = aCoords1->Lower(); i <= aCoords1->Upper(); ++i) + { + if (std::abs(aCoords1->Value(i) - aCoords2->Value(i)) > aTolerance) + { + return false; + } + } + return true; + } +}; + +#endif // _StepTidy_DirectionHasher_HeaderFile diff --git a/src/DataExchange/TKDESTEP/StepTidy/StepTidy_DirectionReducer.cxx b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_DirectionReducer.cxx new file mode 100644 index 0000000000..a1c4749c8b --- /dev/null +++ b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_DirectionReducer.cxx @@ -0,0 +1,82 @@ +// 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 + +//================================================================================================== + +StepTidy_DirectionReducer::StepTidy_DirectionReducer(const Handle(XSControl_WorkSession)& theWS) + : StepTidy_EntityReducer(theWS) +{ + registerReplacer(STANDARD_TYPE(StepGeom_Axis1Placement), replaceAxis1Placement); + registerReplacer(STANDARD_TYPE(StepGeom_Axis2Placement3d), replaceAxis2Placement3d); + registerReplacer(STANDARD_TYPE(StepGeom_Vector), replaceVector); +} + +//================================================================================================== + +bool StepTidy_DirectionReducer::replaceAxis1Placement( + const Handle(StepGeom_Direction)& theOldEntity, + const Handle(StepGeom_Direction)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepGeom_Axis1Placement) aSharing = Handle(StepGeom_Axis1Placement)::DownCast(theSharing); + if (aSharing->Axis() == theOldEntity) + { + aSharing->SetAxis(theNewEntity); + return true; + } + return false; +} + +//================================================================================================== + +bool StepTidy_DirectionReducer::replaceAxis2Placement3d( + const Handle(StepGeom_Direction)& theOldEntity, + const Handle(StepGeom_Direction)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepGeom_Axis2Placement3d) aSharing = + Handle(StepGeom_Axis2Placement3d)::DownCast(theSharing); + if (aSharing->Axis() == theOldEntity) + { + aSharing->SetAxis(theNewEntity); + return true; + } + else if (aSharing->RefDirection() == theOldEntity) + { + aSharing->SetRefDirection(theNewEntity); + return true; + } + return false; +} + +//================================================================================================== + +bool StepTidy_DirectionReducer::replaceVector(const Handle(StepGeom_Direction)& theOldEntity, + const Handle(StepGeom_Direction)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepGeom_Vector) aSharing = Handle(StepGeom_Vector)::DownCast(theSharing); + if (aSharing->Orientation() == theOldEntity) + { + aSharing->SetOrientation(theNewEntity); + return true; + } + return false; +} diff --git a/src/DataExchange/TKDESTEP/StepTidy/StepTidy_DirectionReducer.pxx b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_DirectionReducer.pxx new file mode 100644 index 0000000000..618f2f1802 --- /dev/null +++ b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_DirectionReducer.pxx @@ -0,0 +1,64 @@ +// 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. + +#ifndef _StepTidy_DirectionReducer_HeaderFile +#define _StepTidy_DirectionReducer_HeaderFile + +#include +#include + +#include + +//! Processor for merging StepGeom_Direction entities. +//! This processor merges directions with the same direction ratios and names. +//! The processor replaces all occurrences of the old directions with the new ones. +//! The processor does not remove old directions from the model. +//! See StepTidy_EntityReducer for the description of the Reducer workflow. +class StepTidy_DirectionReducer + : public StepTidy_EntityReducer +{ +public: + //! Constructor. Stores the work session and registers replacer functions. + //! @param theWS the work session. + Standard_EXPORT StepTidy_DirectionReducer(const Handle(XSControl_WorkSession)& theWS); + +private: + //! Replaces the old direction with the new one in the StepGeom_Axis1Placement entity. + //! @param theOldEntity the old direction. + //! @param theNewEntity the new direction. + //! @param theSharing the StepGeom_Axis1Placement entity to update. + //! @return true if the direction was replaced, false otherwise. + static bool replaceAxis1Placement(const Handle(StepGeom_Direction)& theOldEntity, + const Handle(StepGeom_Direction)& theNewEntity, + Handle(Standard_Transient) theSharing); + + //! Replaces the old direction with the new one in the StepGeom_Axis2Placement3d entity. + //! @param theOldEntity the old direction. + //! @param theNewEntity the new direction. + //! @param theSharing the StepGeom_Axis2Placement3d entity to update. + //! @return true if the direction was replaced, false otherwise. + static bool replaceAxis2Placement3d(const Handle(StepGeom_Direction)& theOldEntity, + const Handle(StepGeom_Direction)& theNewEntity, + Handle(Standard_Transient) theSharing); + + //! Replaces the old direction with the new one in the StepGeom_Vector entity. + //! @param theOldEntity the old direction. + //! @param theNewEntity the new direction. + //! @param theSharing the StepGeom_Vector entity to update. + //! @return true if the direction was replaced, false otherwise. + static bool replaceVector(const Handle(StepGeom_Direction)& theOldEntity, + const Handle(StepGeom_Direction)& theNewEntity, + Handle(Standard_Transient) theSharing); +}; + +#endif // _StepTidy_DirectionReducer_HeaderFile diff --git a/src/DataExchange/TKDESTEP/StepTidy/StepTidy_DuplicateCleaner.cxx b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_DuplicateCleaner.cxx new file mode 100644 index 0000000000..5da6f01536 --- /dev/null +++ b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_DuplicateCleaner.cxx @@ -0,0 +1,123 @@ +// 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 + +//================================================================================================== + +StepTidy_DuplicateCleaner::StepTidy_DuplicateCleaner(Handle(XSControl_WorkSession) theWS) + : myWS(theWS) +{ +} + +//================================================================================================== + +void StepTidy_DuplicateCleaner::Perform() +{ + Handle(StepData_StepModel) aModel = Handle(StepData_StepModel)::DownCast(myWS->Model()); + if (aModel.IsNull()) + { + return; + } + + //! Initialize Reducers. + StepTidy_CartesianPointReducer aCartesianPointReducer(myWS); + StepTidy_DirectionReducer aDirectionReducer(myWS); + StepTidy_Axis2Placement3dReducer aAxis2Placement3dReducer(myWS); + StepTidy_VectorReducer aVectorReducer(myWS); + StepTidy_LineReducer aLineReducer(myWS); + StepTidy_PlaneReducer aPlaneReducer(myWS); + StepTidy_CircleReducer aCircleReducer(myWS); + + // Process all entities. + for (Standard_Integer anIndex = 1; anIndex <= aModel->NbEntities(); ++anIndex) + { + const Handle(Standard_Transient) anEntity = aModel->Value(anIndex); + aCartesianPointReducer.ProcessEntity(anEntity); + aDirectionReducer.ProcessEntity(anEntity); + aAxis2Placement3dReducer.ProcessEntity(anEntity); + aVectorReducer.ProcessEntity(anEntity); + aLineReducer.ProcessEntity(anEntity); + aPlaneReducer.ProcessEntity(anEntity); + aCircleReducer.ProcessEntity(anEntity); + } + + // Perform replacement of duplicate entities. + TColStd_MapOfTransient aReplacedEntities; + aCartesianPointReducer.Perform(aReplacedEntities); + aDirectionReducer.Perform(aReplacedEntities); + aAxis2Placement3dReducer.Perform(aReplacedEntities); + aVectorReducer.Perform(aReplacedEntities); + aLineReducer.Perform(aReplacedEntities); + aPlaneReducer.Perform(aReplacedEntities); + aCircleReducer.Perform(aReplacedEntities); + + // Remove duplicate entities. + removeEntities(aReplacedEntities); +} + +//================================================================================================== + +void StepTidy_DuplicateCleaner::removeEntities(const TColStd_MapOfTransient& theToRemove) +{ + if (theToRemove.IsEmpty()) + { + return; + } + // Remove entities. + Handle(StepData_StepModel) anIntermediateModel = new StepData_StepModel(); + Handle(StepData_StepModel) aReadModel = Handle(StepData_StepModel)::DownCast(myWS->Model()); + anIntermediateModel->SetProtocol(aReadModel->Protocol()); + anIntermediateModel->SetGTool(aReadModel->GTool()); + + for (Standard_Integer i = 1; i <= aReadModel->NbEntities(); i++) + { + const Handle(Standard_Transient)& anEnt = aReadModel->Value(i); + if (!theToRemove.Contains(anEnt)) + { + anIntermediateModel->AddWithRefs(anEnt); + } + } + + myWS->SetModel(anIntermediateModel); + myWS->ComputeGraph(); + + // Clean hanged entities. + Handle(StepData_StepModel) aNewModel = new StepData_StepModel(); + aNewModel->SetProtocol(anIntermediateModel->Protocol()); + aNewModel->SetGTool(anIntermediateModel->GTool()); + const auto& aGraph = myWS->Graph(); + + for (Standard_Integer i = 1; i <= anIntermediateModel->NbEntities(); i++) + { + const Handle(Standard_Transient)& anEnt = anIntermediateModel->Value(i); + if (aGraph.Shareds(anEnt).NbEntities() > 0 || aGraph.Sharings(anEnt).NbEntities() > 0) + { + aNewModel->AddWithRefs(anEnt); + } + } + + myWS->SetModel(aNewModel); + myWS->ComputeGraph(); +} diff --git a/src/DataExchange/TKDESTEP/StepTidy/StepTidy_DuplicateCleaner.hxx b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_DuplicateCleaner.hxx new file mode 100644 index 0000000000..d84156b6fb --- /dev/null +++ b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_DuplicateCleaner.hxx @@ -0,0 +1,62 @@ +// 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. + +#ifndef _StepTidy_DuplicateCleaner_HeaderFile +#define _StepTidy_DuplicateCleaner_HeaderFile + +#include + +class XSControl_WorkSession; + +//! A class to merge STEP entities. +//! This class is used to merge equal STEP entities in the work session and remove duplicates. +//! It uses the child classes of StepTidy_EntityReducer class to perform the merging. +//! The child classes of StepTidy_EntityReducer are specialized for different types of entities. +//! StepTidy_EntityReducer implements the basic logic for searching and merging entities +//! while child classes implement the logic for replacing specific type of entities in the specific +//! type of sharing entities. +//! Classes StepTidy_*Hasher are used to hash the entities and compare them. They define which +//! entities are considered equal to each other. The hashers are used in the StepTidy_EntityReducer +//! class to store the entities in a map. The map is used to find the duplicates and replace them. +//! From this perspective of this module, 'equal' or 'duplicate' entities are those that +//! has equal names and very close numerical values, like for example Cartesian points with +//! coordinates that are equal up to 1e-12 or Vectors with equal orientations and magnitudes +//! up to 1e-12. +//! After the merging this class calls its own method to remove the duplicates. +//! How to use: +//! 1. Create an instance of the class by providing a pointer to the work session where the +//! entities to process are stored. +//! 2. Call Perform() method to perform the merging of entities. After this call all entities +//! that are considered equal to each other will be merged, and duplicates will be removed. +class StepTidy_DuplicateCleaner +{ +public: + //! Constructor. + //! @param theWS the work session to merge entities in. + Standard_EXPORT StepTidy_DuplicateCleaner(Handle(XSControl_WorkSession) theWS); + + //! Perform the merging of entities. + //! All entities in a model stored in the provided work session that are considered equal to + //! each other will be merged, and duplicates will be removed. + Standard_EXPORT void Perform(); + +private: + //! Remove entities from the work session. + //! @param theToRemove the entities to remove. + void removeEntities(const TColStd_MapOfTransient& theToRemove); + +private: + Handle(XSControl_WorkSession) myWS; //!< The work session containing the model with entities. +}; + +#endif // _StepTidy_DuplicateCleaner_HeaderFile diff --git a/src/DataExchange/TKDESTEP/StepTidy/StepTidy_EntityReducer.pxx b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_EntityReducer.pxx new file mode 100644 index 0000000000..76576b78e3 --- /dev/null +++ b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_EntityReducer.pxx @@ -0,0 +1,241 @@ +// 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. + +#ifndef _StepTidy_EntityReducer_HeaderFile +#define _StepTidy_EntityReducer_HeaderFile + +#include +#include +#include +#include +#include +#include + +#include + +//! Base class for removing duplicate entities. +//! Implements the logic of processing entities and removing duplicates. +//! Child classes should only implement and register replacer functions +//! for each specific type of sharing entity. +//! How to use: +//! 1. Create an instance of the child class. +//! 2. Add entities to the processor using ProcessEntity() method. Entities +//! that can be merged will be stored in the internal map, others will be ignored. +//! 3. Call Perform() method to replace duplicate entities. After this call +//! all duplicate entities will be replaced in a model with the first processed entity +//! that is evaluated as equal to them. +//! IMPORTANT: Duplicated entities will be replaced but not removed from the model! +//! 4. Call GetReplacedEntities() to get a list of replaced duplicates. This list can be used +//! to remove entities from the model. +//! @tparam ProcessedType Type of the processed entities. +//! @tparam ProcessedTypeHasher OCCT-Style hasher for the processed entities. +template +class StepTidy_EntityReducer +{ +protected: + // Map of duplicate entities. Key is the first processed entity, value is a list of duplicates. + using DuplicateMap = NCollection_DataMap, + ProcessedTypeHasher>; + // Function to replace an entity in sharings. First argument is the old entity, second is the new + // entity, third is the sharing in which the entity should be replaced. Returns true if the entity + // was replaced, false otherwise. + using ReplacerFunction = std::function; + // Map of replacer functions. Key is the type of the sharing entity, value is the replacer + // function for this type. + using ReplacerMap = NCollection_DataMap; + +protected: + //! Constructor. Accepts a work session containing the model to process. + //! Protected to prevent direct instantiation of the base class. Only child classes should be + //! allowed to instantiate. + //! @param theWS Work session. + StepTidy_EntityReducer(const Handle(XSControl_WorkSession)& theWS); + +public: + //! Function to process an entity. If the entity can be merged, it will be stored in the internal + //! map. If the entity cannot be merged, it will be ignored. + //! Entity can only be processed if: + //! 1. The type of entity is ProcessedType. + //! 2. All sharings of the entity have a registered replacer function. + //! @param theEntity Entity to process. + //! @return True if the entity was processed, false if it was ignored. + Standard_EXPORT bool ProcessEntity(const Handle(Standard_Transient)& theEntity); + + //! Function to replace duplicate entities. After this call, all duplicate entities will be + //! replaced with the first processed entity that is evaluated as equal to them. + //! IMPORTANT: Duplicated entities will be replaced but not removed from the model! + //! @param theReplacedEntities List where replaced entities will be stored. + //! This list can be used to remove entities from the model. + Standard_EXPORT void Perform(TColStd_MapOfTransient& theReplacedEntities); + +protected: + //! Register a replacer function for a specific type of sharing entity. + //! Should be used by child classes to register replacer functions for each specific type of + //! sharing entity. If a sharing entity of the specified type is encountered during processing, + //! the registered replacer function will be called to replace the old entity with the new one. + //! All replacers must be registered before calling ProcessEntity() method. + //! @param theType Type of the sharing entity. + //! @param theReplacer Replacer function. + void registerReplacer(const Handle(Standard_Type)& theType, const ReplacerFunction& theReplacer); + +public: + //! Checks if all sharings have registered replacers for their types. + //! @param theSharings List of sharings to check. + //! @return True if all sharings have registered replacers, false otherwise. + bool hasAllReplacers(const Handle(TColStd_HSequenceOfTransient)& theSharings) const; + + //! Replaces an old entity with a new entity in sharings. + //! Should only be called if all sharings have registered replacers. + //! @param theOldEntity Old entity to replace. + //! @param theNewEntity New entity to replace old entity with. + //! @param theSharings List of old entity sharings to replace the entity in. + //! @return True if all entities were replaced, false if at least one entity was not replaced. + bool replaceInSharings(const Handle(ProcessedType)& theOldEntity, + const Handle(ProcessedType)& theNewEntity, + const Handle(TColStd_HSequenceOfTransient)& theSharings) const; + +private: + Handle(XSControl_WorkSession) myWS; //!< Work session. + ReplacerMap myReplacerMap; //!< Map of replacer functions. + DuplicateMap myDuplicateMap; //!< Map of duplicate entities. +}; + +//================================================================================================== + +template +StepTidy_EntityReducer::StepTidy_EntityReducer( + const Handle(XSControl_WorkSession)& theWS) + : myWS(theWS), + myReplacerMap(), + myDuplicateMap() +{ +} + +//================================================================================================== + +template +bool StepTidy_EntityReducer::ProcessEntity( + const Handle(Standard_Transient)& theEntity) +{ + const Handle(ProcessedType) anEntity = Handle(ProcessedType)::DownCast(theEntity); + if (anEntity.IsNull()) + { + return false; + } + const Interface_Graph& aGraph = myWS->Graph(); + const Handle(TColStd_HSequenceOfTransient) aSharings = aGraph.GetSharings(anEntity); + if (hasAllReplacers(aSharings)) + { + std::vector* anIter = myDuplicateMap.ChangeSeek(anEntity); + if (anIter == nullptr) + { + // Add as a new key. + myDuplicateMap.Bind(anEntity, std::vector{}); + } + else + { + // Add as a value. + anIter->push_back(anEntity); + } + } + + return true; +} + +//================================================================================================== + +template +void StepTidy_EntityReducer::Perform( + TColStd_MapOfTransient& theReplacedEntities) +{ + for (typename DuplicateMap::Iterator anIter(myDuplicateMap); anIter.More(); anIter.Next()) + { + const Handle(ProcessedType)& anEntity = anIter.Key(); + const std::vector& aDuplicates = anIter.Value(); + if (aDuplicates.empty()) + { + continue; + } + + const Interface_Graph& aGraph = myWS->Graph(); + for (const auto& aDuplicate : aDuplicates) + { + Handle(TColStd_HSequenceOfTransient) aSharings = aGraph.GetSharings(aDuplicate); + if (aSharings.IsNull()) + { + continue; + } + + if (replaceInSharings(aDuplicate, anEntity, aSharings)) + { + theReplacedEntities.Add(aDuplicate); + } + } + } +} + +//================================================================================================== + +template +void StepTidy_EntityReducer::registerReplacer( + const Handle(Standard_Type)& theType, + const ReplacerFunction& theReplacer) +{ + myReplacerMap.Bind(theType, theReplacer); +} + +//================================================================================================== + +template +bool StepTidy_EntityReducer::hasAllReplacers( + const Handle(TColStd_HSequenceOfTransient)& theSharings) const +{ + if (theSharings.IsNull()) + { + return false; + } + return std::all_of(theSharings->cbegin(), + theSharings->cend(), + [this](const Handle(Standard_Transient)& theSharing) { + return myReplacerMap.IsBound(theSharing->DynamicType()); + }); +} + +//================================================================================================== +template +bool StepTidy_EntityReducer::replaceInSharings( + const Handle(ProcessedType)& theOldEntity, + const Handle(ProcessedType)& theNewEntity, + const Handle(TColStd_HSequenceOfTransient)& theSharings) const +{ + bool isAllReplaced = true; + for (const auto& aSharing : *theSharings) + { + if (aSharing.IsNull()) + { + continue; + } + + const ReplacerFunction& aReplacer = myReplacerMap.Find(aSharing->DynamicType()); + if (!aReplacer(theOldEntity, theNewEntity, aSharing)) + { + isAllReplaced = false; + } + } + return isAllReplaced; +} + +#endif // _StepTidy_EntityReducer_HeaderFile diff --git a/src/DataExchange/TKDESTEP/StepTidy/StepTidy_LineHasher.pxx b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_LineHasher.pxx new file mode 100644 index 0000000000..b1fbff7686 --- /dev/null +++ b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_LineHasher.pxx @@ -0,0 +1,77 @@ +// 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. + +#ifndef _StepTidy_LineHasher_HeaderFile +#define _StepTidy_LineHasher_HeaderFile + +#include +#include + +#include +#include +#include + +//! OCCT-style hasher for StepGeom_Line entities. +struct StepTidy_LineHasher +{ + // Hashes the Line by its name and Line ratios. + std::size_t operator()(const Handle(StepGeom_Line)& theLine) const noexcept + { + const size_t aHashes[2]{StepTidy_CartesianPointHasher{}(theLine->Pnt()), + StepTidy_VectorHasher{}(theLine->Dir())}; + + const size_t aCombinedHash = opencascade::hashBytes(aHashes, sizeof(aHashes)); + if (theLine->Name().IsNull()) + { + // If the name is not present, return the hash. + return aCombinedHash; + } + // Add the name to the hash if it is present. + const size_t aCombinedHashWithName[2]{ + aCombinedHash, + std::hash{}(theLine->Name()->String())}; + return opencascade::hashBytes(aCombinedHashWithName, sizeof(aCombinedHashWithName)); + } + + // Compares two Lines by their names and Line ratios. + bool operator()(const Handle(StepGeom_Line)& theLine1, + const Handle(StepGeom_Line)& theLine2) const noexcept + + { + // Compare names. + if (theLine1->Name().IsNull() != theLine2->Name().IsNull()) + { + return false; + } + if (!theLine1->Name()->IsSameString(theLine2->Name())) + { + return false; + } + + // Compare points. + if (!StepTidy_CartesianPointHasher{}(theLine1->Pnt(), theLine2->Pnt())) + { + return false; + } + + // Compare directions. + if (!StepTidy_VectorHasher{}(theLine1->Dir(), theLine2->Dir())) + { + return false; + } + + return true; + } +}; + +#endif // _StepTidy_LineHasher_HeaderFile diff --git a/src/DataExchange/TKDESTEP/StepTidy/StepTidy_LineReducer.cxx b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_LineReducer.cxx new file mode 100644 index 0000000000..4f55d148dc --- /dev/null +++ b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_LineReducer.cxx @@ -0,0 +1,117 @@ +// 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 + +//================================================================================================== + +StepTidy_LineReducer::StepTidy_LineReducer(const Handle(XSControl_WorkSession)& theWS) + : StepTidy_EntityReducer(theWS) +{ + registerReplacer(STANDARD_TYPE(StepShape_EdgeCurve), replaceEdgeCurve); + registerReplacer(STANDARD_TYPE(StepGeom_TrimmedCurve), replaceTrimmedCurve); + registerReplacer(STANDARD_TYPE(StepGeom_SurfaceCurve), replaceSurfaceCurve); + registerReplacer(STANDARD_TYPE(StepRepr_DefinitionalRepresentation), + replaceDefinitionalRepresentation); + registerReplacer(STANDARD_TYPE(StepGeom_SeamCurve), replaceSeamCurve); +} + +//================================================================================================== + +bool StepTidy_LineReducer::replaceEdgeCurve(const Handle(StepGeom_Line)& theOldEntity, + const Handle(StepGeom_Line)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepShape_EdgeCurve) aSharing = Handle(StepShape_EdgeCurve)::DownCast(theSharing); + if (aSharing->EdgeGeometry() == theOldEntity) + { + aSharing->SetEdgeGeometry(theNewEntity); + return true; + } + return false; +} + +//================================================================================================== + +bool StepTidy_LineReducer::replaceTrimmedCurve(const Handle(StepGeom_Line)& theOldEntity, + const Handle(StepGeom_Line)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepGeom_TrimmedCurve) aSharing = Handle(StepGeom_TrimmedCurve)::DownCast(theSharing); + if (aSharing->BasisCurve() == theOldEntity) + { + aSharing->SetBasisCurve(theNewEntity); + return true; + } + return false; +} + +//================================================================================================== + +bool StepTidy_LineReducer::replaceSurfaceCurve(const Handle(StepGeom_Line)& theOldEntity, + const Handle(StepGeom_Line)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepGeom_SurfaceCurve) aSharing = Handle(StepGeom_SurfaceCurve)::DownCast(theSharing); + if (aSharing->Curve3d() == theOldEntity) + { + aSharing->SetCurve3d(theNewEntity); + return true; + } + return false; +} + +//================================================================================================== + +bool StepTidy_LineReducer::replaceDefinitionalRepresentation( + const Handle(StepGeom_Line)& theOldEntity, + const Handle(StepGeom_Line)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepRepr_DefinitionalRepresentation) aSharing = + Handle(StepRepr_DefinitionalRepresentation)::DownCast(theSharing); + bool isReplaced = false; + Handle(StepRepr_HArray1OfRepresentationItem) anItems = aSharing->Items(); + for (Standard_Integer anIndex = 1; anIndex <= aSharing->NbItems(); ++anIndex) + { + const Handle(StepRepr_RepresentationItem) aRepItem = anItems->Value(anIndex); + if (aRepItem == theOldEntity) + { + anItems->SetValue(anIndex, theNewEntity); + isReplaced = true; + } + } + return isReplaced; +} + +//================================================================================================== + +bool StepTidy_LineReducer::replaceSeamCurve(const Handle(StepGeom_Line)& theOldEntity, + const Handle(StepGeom_Line)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepGeom_SeamCurve) aSharing = Handle(StepGeom_SeamCurve)::DownCast(theSharing); + if (aSharing->Curve3d() == theOldEntity) + { + aSharing->SetCurve3d(theNewEntity); + return true; + } + return false; +} diff --git a/src/DataExchange/TKDESTEP/StepTidy/StepTidy_LineReducer.pxx b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_LineReducer.pxx new file mode 100644 index 0000000000..40e0ca6b35 --- /dev/null +++ b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_LineReducer.pxx @@ -0,0 +1,83 @@ +// 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. + +#ifndef _StepTidy_LineReducer_HeaderFile +#define _StepTidy_LineReducer_HeaderFile + +#include +#include + +#include + +//! Processor for merging StepGeom_Line entities. +//! This processor merges lines with the same point and direction and names. +class StepTidy_LineReducer : public StepTidy_EntityReducer +{ +public: + //! Constructor. Stores the work session and registers replacer functions. + //! @param theWS the work session. + Standard_EXPORT StepTidy_LineReducer(const Handle(XSControl_WorkSession)& theWS); + +private: + //! Replacer function for StepShape_EdgeCurve entities. + //! Replaces the old entity with the new one in the sharing entity. + //! @param theOldEntity the old entity to replace. + //! @param theNewEntity the new entity to replace with. + //! @param theSharing the sharing entity in which to replace the old entity. + //! @return true if the entity was replaced, false otherwise. + static bool replaceEdgeCurve(const Handle(StepGeom_Line)& theOldEntity, + const Handle(StepGeom_Line)& theNewEntity, + Handle(Standard_Transient) theSharing); + + //! Replacer function for StepGeom_TrimmedCurve entities. + //! Replaces the old entity with the new one in the sharing entity. + //! @param theOldEntity the old entity to replace. + //! @param theNewEntity the new entity to replace with. + //! @param theSharing the sharing entity in which to replace the old entity. + //! @return true if the entity was replaced, false otherwise. + static bool replaceTrimmedCurve(const Handle(StepGeom_Line)& theOldEntity, + const Handle(StepGeom_Line)& theNewEntity, + Handle(Standard_Transient) theSharing); + + //! Replacer function for StepGeom_SurfaceCurve entities. + //! Replaces the old entity with the new one in the sharing entity. + //! @param theOldEntity the old entity to replace. + //! @param theNewEntity the new entity to replace with. + //! @param theSharing the sharing entity in which to replace the old entity. + //! @return true if the entity was replaced, false otherwise. + static bool replaceSurfaceCurve(const Handle(StepGeom_Line)& theOldEntity, + const Handle(StepGeom_Line)& theNewEntity, + Handle(Standard_Transient) theSharing); + + //! Replacer function for StepRepr_DefinitionalRepresentation entities. + //! Replaces the old entity with the new one in the sharing entity. + //! @param theOldEntity the old entity to replace. + //! @param theNewEntity the new entity to replace with. + //! @param theSharing the sharing entity in which to replace the old entity. + //! @return true if the entity was replaced, false otherwise. + static bool replaceDefinitionalRepresentation(const Handle(StepGeom_Line)& theOldEntity, + const Handle(StepGeom_Line)& theNewEntity, + Handle(Standard_Transient) theSharing); + + //! Replacer function for StepGeom_SeamCurve entities. + //! Replaces the old entity with the new one in the sharing entity. + //! @param theOldEntity the old entity to replace. + //! @param theNewEntity the new entity to replace with. + //! @param theSharing the sharing entity in which to replace the old entity. + //! @return true if the entity was replaced, false otherwise. + static bool replaceSeamCurve(const Handle(StepGeom_Line)& theOldEntity, + const Handle(StepGeom_Line)& theNewEntity, + Handle(Standard_Transient) theSharing); +}; + +#endif // _StepTidy_LineReducer_HeaderFile diff --git a/src/DataExchange/TKDESTEP/StepTidy/StepTidy_PlaneHasher.pxx b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_PlaneHasher.pxx new file mode 100644 index 0000000000..28d9347cad --- /dev/null +++ b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_PlaneHasher.pxx @@ -0,0 +1,60 @@ +// 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. + +#ifndef _StepTidy_PlaneHasher_HeaderFile +#define _StepTidy_PlaneHasher_HeaderFile + +#include + +#include +#include + +//! OCCT-style hasher for StepGeom_Plane entities. +struct StepTidy_PlaneHasher +{ + // Hashes the axis Planes. + std::size_t operator()(const Handle(StepGeom_Plane)& thePlane) const noexcept + { + const size_t aHash = StepTidy_Axis2Placement3dHasher{}(thePlane->Position()); + if (thePlane->Name().IsNull()) + { + // If the name is not present, return the hash. + return aHash; + } + // Add the name to the hash if it is present. + const size_t aCombinedHashWithName[2]{ + aHash, + std::hash{}(thePlane->Name()->String())}; + return opencascade::hashBytes(aCombinedHashWithName, sizeof(aCombinedHashWithName)); + } + + // Compares two axis Planes. + bool operator()(const Handle(StepGeom_Plane)& thePlane1, + const Handle(StepGeom_Plane)& thePlane2) const noexcept + { + // Compare names. + if (thePlane1->Name().IsNull() != thePlane2->Name().IsNull()) + { + return false; + } + if (!thePlane1->Name()->IsSameString(thePlane2->Name())) + { + return false; + } + + // Compare axis Planes. + return StepTidy_Axis2Placement3dHasher{}(thePlane1->Position(), thePlane2->Position()); + } +}; + +#endif // _StepTidy_PlaneHasher_HeaderFile diff --git a/src/DataExchange/TKDESTEP/StepTidy/StepTidy_PlaneReducer.cxx b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_PlaneReducer.cxx new file mode 100644 index 0000000000..24e5c6261a --- /dev/null +++ b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_PlaneReducer.cxx @@ -0,0 +1,55 @@ +// 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 + +//================================================================================================== + +StepTidy_PlaneReducer::StepTidy_PlaneReducer(const Handle(XSControl_WorkSession)& theWS) + : StepTidy_EntityReducer(theWS) +{ + registerReplacer(STANDARD_TYPE(StepShape_AdvancedFace), replaceAdvancedFace); + registerReplacer(STANDARD_TYPE(StepGeom_Pcurve), replacePcurve); +} + +//================================================================================================== + +bool StepTidy_PlaneReducer::replaceAdvancedFace(const Handle(StepGeom_Plane)& theOldEntity, + const Handle(StepGeom_Plane)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepShape_AdvancedFace) aSharing = Handle(StepShape_AdvancedFace)::DownCast(theSharing); + if (aSharing->FaceGeometry() == theOldEntity) + { + aSharing->SetFaceGeometry(theNewEntity); + return true; + } + return false; +} + +//================================================================================================== +bool StepTidy_PlaneReducer::replacePcurve(const Handle(StepGeom_Plane)& theOldEntity, + const Handle(StepGeom_Plane)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepGeom_Pcurve) aSharing = Handle(StepGeom_Pcurve)::DownCast(theSharing); + if (aSharing->BasisSurface() == theOldEntity) + { + aSharing->SetBasisSurface(theNewEntity); + return true; + } + return false; +} diff --git a/src/DataExchange/TKDESTEP/StepTidy/StepTidy_PlaneReducer.pxx b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_PlaneReducer.pxx new file mode 100644 index 0000000000..90d753bd2a --- /dev/null +++ b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_PlaneReducer.pxx @@ -0,0 +1,53 @@ +// 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. + +#ifndef _StepTidy_PlaneReducer_HeaderFile +#define _StepTidy_PlaneReducer_HeaderFile + +#include +#include + +#include + +//! Processor for merging StepGeom_Plane entities. +//! This processor merges planes with the same names and placements. +class StepTidy_PlaneReducer : public StepTidy_EntityReducer +{ +public: + //! Constructor. Stores the work session and registers replacer functions. + //! @param theWS the work session. + Standard_EXPORT StepTidy_PlaneReducer(const Handle(XSControl_WorkSession)& theWS); + +private: + //! Replacer function for StepShape_AdvancedFace entities. + //! Replaces the old entity with the new one in the sharing entity. + //! @param theOldEntity the old entity to replace. + //! @param theNewEntity the new entity to replace with. + //! @param theSharing the sharing StepShape_AdvancedFace in which to replace the old entity. + //! @return true if the entity was replaced, false otherwise. + static bool replaceAdvancedFace(const Handle(StepGeom_Plane)& theOldEntity, + const Handle(StepGeom_Plane)& theNewEntity, + Handle(Standard_Transient) theSharing); + + //! Replacer function for StepGeom_Pcurve entities. + //! Replaces the old entity with the new one in the sharing entity. + //! @param theOldEntity the old entity to replace. + //! @param theNewEntity the new entity to replace with. + //! @param theSharing the sharing StepGeom_Pcurve in which to replace the old entity. + //! @return true if the entity was replaced, false otherwise. + static bool replacePcurve(const Handle(StepGeom_Plane)& theOldEntity, + const Handle(StepGeom_Plane)& theNewEntity, + Handle(Standard_Transient) theSharing); +}; + +#endif // _StepTidy_DirectionReducer_HeaderFile diff --git a/src/DataExchange/TKDESTEP/StepTidy/StepTidy_VectorHasher.pxx b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_VectorHasher.pxx new file mode 100644 index 0000000000..7f7d69e62f --- /dev/null +++ b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_VectorHasher.pxx @@ -0,0 +1,70 @@ +// 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. + +#ifndef _StepTidy_VectorHasher_HeaderFile +#define _StepTidy_VectorHasher_HeaderFile + +#include + +#include +#include +#include + +//! OCCT-style hasher for StepGeom_Vector entities. +struct StepTidy_VectorHasher +{ + // Hashes the Vector by its name and Vector ratios. + std::size_t operator()(const Handle(StepGeom_Vector)& theVector) const noexcept + { + const size_t aHashes[2]{StepTidy_DirectionHasher{}(theVector->Orientation()), + opencascade::hash(static_cast(theVector->Magnitude()))}; + const size_t aCombinedHash = opencascade::hashBytes(aHashes, sizeof(aHashes)); + if (theVector->Name().IsNull()) + { + // If the name is not present, return the hash. + return aCombinedHash; + } + // Add the name to the hash if it is present. + const size_t aCombinedHashWithName[2]{ + aCombinedHash, + std::hash{}(theVector->Name()->String())}; + return opencascade::hashBytes(aCombinedHashWithName, sizeof(aCombinedHashWithName)); + } + + // Compares two Vectors by their names and Vector ratios. + bool operator()(const Handle(StepGeom_Vector)& theVector1, + const Handle(StepGeom_Vector)& theVector2) const noexcept + { + // Compare names. + if (theVector1->Name().IsNull() != theVector2->Name().IsNull()) + { + return false; + } + if (!theVector1->Name()->IsSameString(theVector2->Name())) + { + return false; + } + + // Compare magnitudes. + constexpr double aTolerance = 1e-12; + if (fabs(theVector1->Magnitude() - theVector2->Magnitude()) > aTolerance) + { + return false; + } + + // Compare orientations. + return StepTidy_DirectionHasher{}(theVector1->Orientation(), theVector2->Orientation()); + } +}; + +#endif // _StepTidy_VectorHasher_HeaderFile diff --git a/src/DataExchange/TKDESTEP/StepTidy/StepTidy_VectorReducer.cxx b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_VectorReducer.cxx new file mode 100644 index 0000000000..94a1a941fa --- /dev/null +++ b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_VectorReducer.cxx @@ -0,0 +1,41 @@ +// 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 + +//================================================================================================== + +StepTidy_VectorReducer::StepTidy_VectorReducer(const Handle(XSControl_WorkSession)& theWS) + : StepTidy_EntityReducer(theWS) +{ + registerReplacer(STANDARD_TYPE(StepGeom_Line), replaceLine); +} + +//================================================================================================== + +bool StepTidy_VectorReducer::replaceLine(const Handle(StepGeom_Vector)& theOldEntity, + const Handle(StepGeom_Vector)& theNewEntity, + Handle(Standard_Transient) theSharing) +{ + Handle(StepGeom_Line) aLine = Handle(StepGeom_Line)::DownCast(theSharing); + if (aLine->Dir() == theOldEntity) + { + aLine->SetDir(theNewEntity); + return true; + } + return false; +} diff --git a/src/DataExchange/TKDESTEP/StepTidy/StepTidy_VectorReducer.pxx b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_VectorReducer.pxx new file mode 100644 index 0000000000..e69b26351e --- /dev/null +++ b/src/DataExchange/TKDESTEP/StepTidy/StepTidy_VectorReducer.pxx @@ -0,0 +1,42 @@ +// 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. + +#ifndef _StepTidy_VectorReducer_HeaderFile +#define _StepTidy_VectorReducer_HeaderFile + +#include +#include + +#include + +//! Processor for merging StepGeom_Vector entities. +//! This processor merges vectors with the same orientation and magnitude and names. +class StepTidy_VectorReducer : public StepTidy_EntityReducer +{ +public: + //! Constructor. Stores the work session and registers replacer functions. + //! @param theWS the work session. + Standard_EXPORT StepTidy_VectorReducer(const Handle(XSControl_WorkSession)& theWS); + +private: + //! Replaces the old vector with the new one in the StepGeom_Line entity. + //! @param theOldEntity the old vector. + //! @param theNewEntity the new vector to replace the old one. + //! @param theSharing the StepGeom_Line entity to update. + //! @return true if the vector was replaced, false otherwise. + static bool replaceLine(const Handle(StepGeom_Vector)& theOldEntity, + const Handle(StepGeom_Vector)& theNewEntity, + Handle(Standard_Transient) theSharing); +}; + +#endif // _StepTidy_VectorReducer_HeaderFile diff --git a/src/Draw/TKXSDRAWSTEP/XSDRAWSTEP/XSDRAWSTEP.cxx b/src/Draw/TKXSDRAWSTEP/XSDRAWSTEP/XSDRAWSTEP.cxx index a3bd3ac0da..5889b3be95 100644 --- a/src/Draw/TKXSDRAWSTEP/XSDRAWSTEP/XSDRAWSTEP.cxx +++ b/src/Draw/TKXSDRAWSTEP/XSDRAWSTEP/XSDRAWSTEP.cxx @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -1094,39 +1093,6 @@ static Standard_Integer WriteStep(Draw_Interpretor& theDI, //================================================================================================= -static Standard_Integer MergeSTEPEntities(Draw_Interpretor& theDI, - Standard_Integer theNbArgs, - const char** theArgVec) -{ - if (theNbArgs < 2) - { - theDI << "Incorrect number of arguments\n"; - theDI << "Usage: MergeSTEPEntities input_file output_file\n"; - return 1; - } - - STEPControl_Reader aReader; - if (aReader.ReadFile(theArgVec[1]) != IFSelect_RetDone) - { - theDI << "Error: Cannot read file " << theArgVec[1] << "\n"; - return 1; - } - - MergeSTEPEntities_Merger aMerger(aReader.WS()); - aMerger.Perform(); - - STEPControl_Writer aWriter(aReader.WS(), Standard_False); - if (aWriter.Write(theArgVec[2]) != IFSelect_RetDone) - { - theDI << "Error: Cannot write file " << theArgVec[2] << "\n"; - return 1; - } - - return 0; -} - -//================================================================================================= - void XSDRAWSTEP::Factory(Draw_Interpretor& theDI) { static Standard_Boolean aIsActivated = Standard_False; @@ -1179,15 +1145,6 @@ void XSDRAWSTEP::Factory(Draw_Interpretor& theDI) WriteStep, aGroup); - theDI.Add("MergeSTEPEntities", - "MergeSTEPEntities input_file output_file" - "\n\t\t: Merge equal entities in STEP file" - "\n\t\t: input_file - Step file to read" - "\n\t\t: output_file - Step file to write output to", - __FILE__, - MergeSTEPEntities, - aGroup); - // Load XSDRAW session for pilot activation XSDRAW::LoadDraw(theDI); }