mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-10 18:51:21 +03:00
Data Exchange, Step Export - Decreasing file size #475
Functionality to remove duplicate entities from Step graph is added. Class MergeSTEPEntities_Merger is main entry point. Class MergeSTEPEntities_EntityProcessor implements the basic replacement logic. Children of MergeSTEPEntities_EntityProcessor implement the logic for the replacement of particular step entity.
This commit is contained in:
parent
00ef3523af
commit
81efe3d3ed
@ -194,6 +194,8 @@ bool DESTEP_ConfigurationNode::Load(const Handle(DE_ConfigurationContext)& theRe
|
||||
(STEPControl_StepModelType)theResource->IntegerVal("write.model.type",
|
||||
InternalParameters.WriteModelType,
|
||||
aScope);
|
||||
InternalParameters.CleanDuplicates =
|
||||
theResource->BooleanVal("write.cleanduplicates", InternalParameters.CleanDuplicates, aScope);
|
||||
|
||||
return DE_ShapeFixConfigurationNode::Load(theResource);
|
||||
}
|
||||
@ -562,6 +564,13 @@ TCollection_AsciiString DESTEP_ConfigurationNode::Save() const
|
||||
aResult += aScope + "write.model.type :\t " + InternalParameters.WriteModelType + "\n";
|
||||
aResult += "!\n";
|
||||
|
||||
aResult += "!\n";
|
||||
aResult += "!Setting up a flag that indicates whether or not duplicate entities should be "
|
||||
"removed from the model befor writing.\n";
|
||||
aResult += "!Default value: -. Available values: \"-\", \"+\"\n";
|
||||
aResult += aScope + "write.cleanduplicates :\t " + InternalParameters.CleanDuplicates + "\n";
|
||||
aResult += "!\n";
|
||||
|
||||
aResult += DE_ShapeFixConfigurationNode::Save();
|
||||
|
||||
aResult += "!*****************************************************************************\n";
|
||||
|
@ -200,6 +200,7 @@ public:
|
||||
bool WriteLayer = true; //<! LayerMode is used to indicate write Layers or not
|
||||
bool WriteProps = true; //<! PropsMode is used to indicate write Validation properties or not
|
||||
STEPControl_StepModelType WriteModelType = STEPControl_AsIs; //<! Gives you the choice of translation mode for an Open CASCADE shape that is being translated to STEP
|
||||
bool CleanDuplicates = false; //<! Indicates whether to remove duplicate entities from the STEP file
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
|
@ -116,6 +116,7 @@ bool DESTEP_Provider::Write(const TCollection_AsciiString& thePath,
|
||||
aWriter.SetLayerMode(aNode->InternalParameters.WriteLayer);
|
||||
aWriter.SetPropsMode(aNode->InternalParameters.WriteProps);
|
||||
aWriter.SetShapeFixParameters(aNode->ShapeFixParameters);
|
||||
aWriter.SetCleanDuplicates(aNode->InternalParameters.CleanDuplicates);
|
||||
DESTEP_Parameters aParams = aNode->InternalParameters;
|
||||
Standard_Real aScaleFactorMM = 1.;
|
||||
if (XCAFDoc_DocumentTool::GetLengthUnit(theDocument,
|
||||
@ -274,6 +275,11 @@ bool DESTEP_Provider::Write(const TCollection_AsciiString& thePath,
|
||||
<< "\t: abandon, no model loaded";
|
||||
return false;
|
||||
}
|
||||
if (aNode->InternalParameters.CleanDuplicates)
|
||||
{
|
||||
aWriter.CleanDuplicateEntities();
|
||||
}
|
||||
|
||||
if (aWriter.Write(thePath.ToCString()) != IFSelect_RetDone)
|
||||
{
|
||||
Message::SendFail() << "DESTEP_Provider: Error on writing file";
|
||||
|
@ -2,4 +2,13 @@
|
||||
set(OCCT_TKDESTEP_GTests_FILES_LOCATION "${CMAKE_CURRENT_LIST_DIR}")
|
||||
|
||||
set(OCCT_TKDESTEP_GTests_FILES
|
||||
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
|
||||
)
|
||||
|
@ -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 <StepTidy_Axis2Placement3dReducer.pxx>
|
||||
|
||||
#include <StepGeom_Plane.hxx>
|
||||
#include <StepRepr_ItemDefinedTransformation.hxx>
|
||||
#include <StepGeom_CylindricalSurface.hxx>
|
||||
#include <StepShape_ShapeRepresentation.hxx>
|
||||
#include <StepRepr_RepresentationContext.hxx>
|
||||
#include <StepRepr_ConstructiveGeometryRepresentation.hxx>
|
||||
#include <StepGeom_Circle.hxx>
|
||||
#include <StepVisual_PresentationLayerAssignment.hxx>
|
||||
#include <StepVisual_StyledItem.hxx>
|
||||
#include <StepGeom_Ellipse.hxx>
|
||||
#include <StepGeom_ConicalSurface.hxx>
|
||||
#include <StepGeom_ToroidalSurface.hxx>
|
||||
#include <StepShape_AdvancedBrepShapeRepresentation.hxx>
|
||||
#include <StepGeom_SphericalSurface.hxx>
|
||||
|
||||
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));
|
||||
}
|
194
src/DataExchange/TKDESTEP/GTests/StepTidy_BaseTestFixture.pxx
Normal file
194
src/DataExchange/TKDESTEP/GTests/StepTidy_BaseTestFixture.pxx
Normal file
@ -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 <STEPControl_Controller.hxx>
|
||||
#include <StepGeom_Axis2Placement3d.hxx>
|
||||
#include <StepGeom_CartesianPoint.hxx>
|
||||
#include <StepGeom_Circle.hxx>
|
||||
#include <StepGeom_Direction.hxx>
|
||||
#include <StepGeom_Line.hxx>
|
||||
#include <StepGeom_Plane.hxx>
|
||||
#include <StepGeom_Vector.hxx>
|
||||
#include <XSControl_WorkSession.hxx>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
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
|
@ -0,0 +1,598 @@
|
||||
// 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 <StepTidy_CartesianPointReducer.pxx>
|
||||
|
||||
#include <StepGeom_Axis1Placement.hxx>
|
||||
#include <StepGeom_Axis2Placement3d.hxx>
|
||||
#include <StepGeom_BSplineCurveWithKnots.hxx>
|
||||
#include <StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve.hxx>
|
||||
#include <StepGeom_BSplineSurfaceWithKnots.hxx>
|
||||
#include <StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface.hxx>
|
||||
#include <StepGeom_Line.hxx>
|
||||
#include <StepGeom_RationalBSplineSurface.hxx>
|
||||
#include <StepRepr_Representation.hxx>
|
||||
#include <StepRepr_RepresentationContext.hxx>
|
||||
#include <StepShape_GeometricCurveSet.hxx>
|
||||
#include <StepShape_VertexPoint.hxx>
|
||||
#include <StepVisual_PresentationLayerAssignment.hxx>
|
||||
#include <StepVisual_StyledItem.hxx>
|
||||
|
||||
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 rational BSpline surface to use.
|
||||
Handle(StepGeom_RationalBSplineSurface) aRationalBSplineSurface =
|
||||
new StepGeom_RationalBSplineSurface;
|
||||
aRationalBSplineSurface->Init(new TCollection_HAsciiString,
|
||||
1,
|
||||
1,
|
||||
new StepGeom_HArray2OfCartesianPoint(1, 1, 1, 1),
|
||||
StepGeom_bssfUnspecified,
|
||||
StepData_LUnknown,
|
||||
StepData_LUnknown,
|
||||
StepData_LUnknown,
|
||||
new TColStd_HArray2OfReal(1, 1, 1, 1));
|
||||
|
||||
// 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,
|
||||
aRationalBSplineSurface);
|
||||
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,
|
||||
aSecondBSSWN,
|
||||
aRationalBSplineSurface);
|
||||
|
||||
// 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));
|
||||
}
|
165
src/DataExchange/TKDESTEP/GTests/StepTidy_CircleReducer_Test.cxx
Normal file
165
src/DataExchange/TKDESTEP/GTests/StepTidy_CircleReducer_Test.cxx
Normal file
@ -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 <StepTidy_CircleReducer.pxx>
|
||||
|
||||
#include <StepShape_EdgeCurve.hxx>
|
||||
#include <StepGeom_SurfaceCurve.hxx>
|
||||
#include <StepGeom_SeamCurve.hxx>
|
||||
|
||||
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));
|
||||
}
|
@ -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 <StepTidy_DirectionReducer.pxx>
|
||||
|
||||
#include <StepGeom_Axis1Placement.hxx>
|
||||
#include <StepGeom_Axis2Placement3d.hxx>
|
||||
|
||||
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));
|
||||
}
|
239
src/DataExchange/TKDESTEP/GTests/StepTidy_LineReducer_Test.cxx
Normal file
239
src/DataExchange/TKDESTEP/GTests/StepTidy_LineReducer_Test.cxx
Normal file
@ -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 <StepTidy_LineReducer.pxx>
|
||||
|
||||
#include <StepShape_EdgeCurve.hxx>
|
||||
#include <StepGeom_TrimmedCurve.hxx>
|
||||
#include <StepGeom_SurfaceCurve.hxx>
|
||||
#include <StepRepr_DefinitionalRepresentation.hxx>
|
||||
#include <StepGeom_SeamCurve.hxx>
|
||||
#include <StepRepr_RepresentationContext.hxx>
|
||||
|
||||
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));
|
||||
}
|
113
src/DataExchange/TKDESTEP/GTests/StepTidy_Merger_Test.cxx
Normal file
113
src/DataExchange/TKDESTEP/GTests/StepTidy_Merger_Test.cxx
Normal file
@ -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 <StepTidy_DuplicateCleaner.hxx>
|
||||
|
||||
#include <StepGeom_Axis1Placement.hxx>
|
||||
|
||||
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);
|
||||
}
|
128
src/DataExchange/TKDESTEP/GTests/StepTidy_PlaneReducer_Test.cxx
Normal file
128
src/DataExchange/TKDESTEP/GTests/StepTidy_PlaneReducer_Test.cxx
Normal file
@ -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 <StepTidy_PlaneReducer.pxx>
|
||||
|
||||
#include <StepShape_AdvancedFace.hxx>
|
||||
#include <StepGeom_Pcurve.hxx>
|
||||
#include <StepRepr_DefinitionalRepresentation.hxx>
|
||||
|
||||
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));
|
||||
}
|
@ -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 <StepTidy_VectorReducer.pxx>
|
||||
|
||||
#include <StepGeom_Line.hxx>
|
||||
|
||||
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));
|
||||
}
|
@ -41,4 +41,5 @@ set(OCCT_TKDESTEP_LIST_OF_PACKAGES
|
||||
APIHeaderSection
|
||||
HeaderSection
|
||||
DESTEP
|
||||
StepTidy
|
||||
)
|
||||
|
@ -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++)
|
||||
{
|
||||
|
@ -446,6 +446,16 @@ void RWStepGeom_RWBSplineSurfaceWithKnots::Check(
|
||||
{
|
||||
ach->AddFail("ERROR: No.of KnotMultiplicities not equal No.of Knots in V");
|
||||
}
|
||||
if (nbMulU == 0)
|
||||
{
|
||||
ach->AddWarning("WARNING: No.of KnotMultiplicities in U is zero");
|
||||
return;
|
||||
}
|
||||
if (nbMulV == 0)
|
||||
{
|
||||
ach->AddWarning("WARNING: No.of KnotMultiplicities in V is zero");
|
||||
return;
|
||||
}
|
||||
|
||||
// check in U direction
|
||||
|
||||
|
@ -249,7 +249,8 @@ STEPCAFControl_Writer::STEPCAFControl_Writer()
|
||||
myPropsMode(Standard_True),
|
||||
mySHUOMode(Standard_True),
|
||||
myGDTMode(Standard_True),
|
||||
myMatMode(Standard_True)
|
||||
myMatMode(Standard_True),
|
||||
myIsCleanDuplicates(Standard_False)
|
||||
{
|
||||
STEPCAFControl_Controller::Init();
|
||||
Handle(XSControl_WorkSession) aWS = new XSControl_WorkSession;
|
||||
@ -266,7 +267,8 @@ STEPCAFControl_Writer::STEPCAFControl_Writer(const Handle(XSControl_WorkSession)
|
||||
myPropsMode(Standard_True),
|
||||
mySHUOMode(Standard_True),
|
||||
myGDTMode(Standard_True),
|
||||
myMatMode(Standard_True)
|
||||
myMatMode(Standard_True),
|
||||
myIsCleanDuplicates(Standard_False)
|
||||
{
|
||||
STEPCAFControl_Controller::Init();
|
||||
Init(theWS, theScratch);
|
||||
@ -292,6 +294,12 @@ void STEPCAFControl_Writer::Init(const Handle(XSControl_WorkSession)& theWS,
|
||||
|
||||
IFSelect_ReturnStatus STEPCAFControl_Writer::Write(const Standard_CString theFileName)
|
||||
{
|
||||
if (myIsCleanDuplicates)
|
||||
{
|
||||
// remove duplicates
|
||||
myWriter.CleanDuplicateEntities();
|
||||
}
|
||||
|
||||
IFSelect_ReturnStatus aStatus = myWriter.Write(theFileName);
|
||||
if (aStatus != IFSelect_RetDone)
|
||||
{
|
||||
|
@ -226,6 +226,18 @@ public:
|
||||
|
||||
Standard_Boolean GetMaterialMode() const { return myMatMode; }
|
||||
|
||||
//! Set clean duplicates flag.
|
||||
//! If set to True, duplicates will be removed from the model.
|
||||
//! @param theCleanDuplicates the flag to set.
|
||||
void SetCleanDuplicates(const Standard_Boolean theCleanDuplicates)
|
||||
{
|
||||
myIsCleanDuplicates = theCleanDuplicates;
|
||||
}
|
||||
|
||||
//! Returns the flag indicating whether duplicates should be removed from the model.
|
||||
//! @return the flag indicating whether duplicates should be removed from the model.
|
||||
Standard_Boolean GetCleanDuplicates() const { return myIsCleanDuplicates; }
|
||||
|
||||
//! Sets parameters for shape processing.
|
||||
//! @param theParameters the parameters for shape processing.
|
||||
Standard_EXPORT void SetShapeFixParameters(
|
||||
@ -382,7 +394,8 @@ private:
|
||||
MoniTool_DataMapOfShapeTransient myMapCompMDGPR;
|
||||
Standard_Boolean myGDTMode;
|
||||
Standard_Boolean myMatMode;
|
||||
NCollection_Vector<Handle(StepRepr_RepresentationItem)> myGDTAnnotations;
|
||||
Standard_Boolean myIsCleanDuplicates;
|
||||
NCollection_Vector<Handle(StepRepr_RepresentationItem)> myGDTAnnotations;
|
||||
Handle(StepVisual_DraughtingModel) myGDTPresentationDM;
|
||||
Handle(StepVisual_HArray1OfPresentationStyleAssignment) myGDTPrsCurveStyle;
|
||||
Handle(StepRepr_ProductDefinitionShape) myGDTCommonPDS;
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <StepData_StepModel.hxx>
|
||||
#include <StepData_Protocol.hxx>
|
||||
#include <StepData_StepWriter.hxx>
|
||||
#include <StepTidy_DuplicateCleaner.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <XSAlgo.hxx>
|
||||
@ -197,6 +198,14 @@ void STEPControl_Writer::PrintStatsTransfer(const Standard_Integer what,
|
||||
thesession->TransferWriter()->PrintStats(what, mode);
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
Standard_EXPORT void STEPControl_Writer::CleanDuplicateEntities()
|
||||
{
|
||||
StepTidy_DuplicateCleaner aCleaner(thesession);
|
||||
aCleaner.Perform();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
void STEPControl_Writer::SetShapeFixParameters(
|
||||
|
@ -131,6 +131,8 @@ public:
|
||||
Standard_EXPORT void PrintStatsTransfer(const Standard_Integer what,
|
||||
const Standard_Integer mode = 0) const;
|
||||
|
||||
Standard_EXPORT void CleanDuplicateEntities();
|
||||
|
||||
//! Sets parameters for shape processing.
|
||||
//! @param theParameters the parameters for shape processing.
|
||||
Standard_EXPORT void SetShapeFixParameters(
|
||||
|
@ -39,6 +39,7 @@ void StepGeom_CartesianPoint::Init2D(const Handle(TCollection_HAsciiString)& aNa
|
||||
nbcoord = 2;
|
||||
coords[0] = X;
|
||||
coords[1] = Y;
|
||||
coords[2] = 0;
|
||||
// --- classe inherited fields ---
|
||||
StepRepr_RepresentationItem::Init(aName);
|
||||
}
|
||||
@ -65,13 +66,14 @@ void StepGeom_CartesianPoint::SetCoordinates(const Handle(TColStd_HArray1OfReal)
|
||||
// coordinates = aCoordinates;
|
||||
}
|
||||
|
||||
Handle(TColStd_HArray1OfReal) StepGeom_CartesianPoint::Coordinates() const
|
||||
void StepGeom_CartesianPoint::SetCoordinates(const std::array<Standard_Real, 3>& theCoordinates)
|
||||
{
|
||||
Handle(TColStd_HArray1OfReal) coordinates = new TColStd_HArray1OfReal(1, nbcoord);
|
||||
coordinates->SetValue(1, coords[0]);
|
||||
coordinates->SetValue(2, coords[1]);
|
||||
coordinates->SetValue(3, coords[2]);
|
||||
return coordinates;
|
||||
coords = theCoordinates;
|
||||
}
|
||||
|
||||
const std::array<Standard_Real, 3>& StepGeom_CartesianPoint::Coordinates() const
|
||||
{
|
||||
return coords;
|
||||
}
|
||||
|
||||
Standard_Real StepGeom_CartesianPoint::CoordinatesValue(const Standard_Integer num) const
|
||||
|
@ -23,6 +23,9 @@
|
||||
#include <Standard_Integer.hxx>
|
||||
#include <StepGeom_Point.hxx>
|
||||
#include <TColStd_HArray1OfReal.hxx>
|
||||
|
||||
#include <array>
|
||||
|
||||
class TCollection_HAsciiString;
|
||||
|
||||
class StepGeom_CartesianPoint;
|
||||
@ -49,7 +52,9 @@ public:
|
||||
|
||||
Standard_EXPORT void SetCoordinates(const Handle(TColStd_HArray1OfReal)& aCoordinates);
|
||||
|
||||
Standard_EXPORT Handle(TColStd_HArray1OfReal) Coordinates() const;
|
||||
Standard_EXPORT void SetCoordinates(const std::array<Standard_Real, 3>& theCoordinates);
|
||||
|
||||
Standard_EXPORT const std::array<Standard_Real, 3>& Coordinates() const;
|
||||
|
||||
Standard_EXPORT Standard_Real CoordinatesValue(const Standard_Integer num) const;
|
||||
|
||||
@ -59,8 +64,8 @@ public:
|
||||
|
||||
protected:
|
||||
private:
|
||||
Standard_Integer nbcoord;
|
||||
Standard_Real coords[3];
|
||||
Standard_Integer nbcoord;
|
||||
std::array<Standard_Real, 3> coords;
|
||||
};
|
||||
|
||||
#endif // _StepGeom_CartesianPoint_HeaderFile
|
||||
|
30
src/DataExchange/TKDESTEP/StepTidy/FILES.cmake
Normal file
30
src/DataExchange/TKDESTEP/StepTidy/FILES.cmake
Normal file
@ -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
|
||||
)
|
@ -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 <StepTidy_CartesianPointHasher.pxx>
|
||||
#include <StepTidy_DirectionHasher.pxx>
|
||||
|
||||
#include <Standard_HashUtils.hxx>
|
||||
#include <StepGeom_Axis2Placement2d.hxx>
|
||||
|
||||
//! 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<TCollection_AsciiString>{}(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
|
@ -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 <StepTidy_CartesianPointHasher.pxx>
|
||||
#include <StepTidy_DirectionHasher.pxx>
|
||||
|
||||
#include <Standard_HashUtils.hxx>
|
||||
#include <StepGeom_Axis2Placement3d.hxx>
|
||||
|
||||
//! 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<TCollection_AsciiString>{}(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
|
@ -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 <StepTidy_Axis2Placement3dReducer.pxx>
|
||||
|
||||
#include <StepGeom_Plane.hxx>
|
||||
#include <StepRepr_ItemDefinedTransformation.hxx>
|
||||
#include <StepGeom_CylindricalSurface.hxx>
|
||||
#include <StepShape_ShapeRepresentation.hxx>
|
||||
#include <StepRepr_ConstructiveGeometryRepresentation.hxx>
|
||||
#include <StepGeom_Circle.hxx>
|
||||
#include <StepVisual_PresentationLayerAssignment.hxx>
|
||||
#include <StepVisual_StyledItem.hxx>
|
||||
#include <StepGeom_Ellipse.hxx>
|
||||
#include <StepGeom_ConicalSurface.hxx>
|
||||
#include <StepGeom_ToroidalSurface.hxx>
|
||||
#include <StepShape_AdvancedBrepShapeRepresentation.hxx>
|
||||
#include <StepGeom_SphericalSurface.hxx>
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
StepTidy_Axis2Placement3dReducer::StepTidy_Axis2Placement3dReducer(
|
||||
const Handle(XSControl_WorkSession)& theWS)
|
||||
: StepTidy_EntityReducer<StepGeom_Axis2Placement3d, StepTidy_Axis2Placement3dHasher>(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;
|
||||
}
|
@ -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 <StepTidy_EntityReducer.pxx>
|
||||
#include <StepTidy_Axis2Placement3dHasher.pxx>
|
||||
|
||||
#include <StepGeom_Axis2Placement3d.hxx>
|
||||
|
||||
//! 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<StepGeom_Axis2Placement3d, StepTidy_Axis2Placement3dHasher>
|
||||
{
|
||||
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
|
@ -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 <Standard_HashUtils.hxx>
|
||||
#include <StepGeom_CartesianPoint.hxx>
|
||||
#include <TCollection_HAsciiString.hxx>
|
||||
|
||||
//! 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<Standard_Real, 3>& aCoords = theCartesianPoint->Coordinates();
|
||||
// If Cartesian point has no name, hash only coordinates.
|
||||
if (theCartesianPoint->Name().IsNull())
|
||||
{
|
||||
return opencascade::hashBytes(aCoords.data(), static_cast<int>(aCoords.size()));
|
||||
}
|
||||
// Otherwise, hash both coordinates and name.
|
||||
const size_t aHashes[2]{
|
||||
opencascade::hashBytes(aCoords.data(), static_cast<int>(aCoords.size())),
|
||||
std::hash<TCollection_AsciiString>{}(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<Standard_Real, 3>& aCoords1 = theCartesianPoint1->Coordinates();
|
||||
const std::array<Standard_Real, 3>& aCoords2 = theCartesianPoint2->Coordinates();
|
||||
if (theCartesianPoint1->NbCoordinates() != theCartesianPoint2->NbCoordinates())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for (int anIndex = 0; anIndex < theCartesianPoint1->NbCoordinates(); ++anIndex)
|
||||
{
|
||||
if (std::abs(aCoords1[anIndex] - aCoords2[anIndex]) > aTolerance)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // _StepTidy_CartesianPointHasher_HeaderFile
|
@ -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 <StepTidy_CartesianPointReducer.pxx>
|
||||
|
||||
#include <Interface_Graph.hxx>
|
||||
#include <StepGeom_Axis1Placement.hxx>
|
||||
#include <StepGeom_Axis2Placement3d.hxx>
|
||||
#include <StepGeom_BSplineCurveWithKnots.hxx>
|
||||
#include <StepGeom_BSplineCurveWithKnotsAndRationalBSplineCurve.hxx>
|
||||
#include <StepGeom_BSplineSurfaceWithKnots.hxx>
|
||||
#include <StepGeom_BSplineSurfaceWithKnotsAndRationalBSplineSurface.hxx>
|
||||
#include <StepGeom_Line.hxx>
|
||||
#include <StepRepr_Representation.hxx>
|
||||
#include <StepShape_GeometricCurveSet.hxx>
|
||||
#include <StepShape_VertexPoint.hxx>
|
||||
#include <StepVisual_PresentationLayerAssignment.hxx>
|
||||
#include <StepVisual_StyledItem.hxx>
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
StepTidy_CartesianPointReducer::StepTidy_CartesianPointReducer(
|
||||
const Handle(XSControl_WorkSession)& theWS)
|
||||
: StepTidy_EntityReducer<StepGeom_CartesianPoint, StepTidy_CartesianPointHasher>(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;
|
||||
}
|
@ -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 <StepTidy_EntityReducer.pxx>
|
||||
#include <StepTidy_CartesianPointHasher.pxx>
|
||||
|
||||
#include <StepGeom_CartesianPoint.hxx>
|
||||
|
||||
//! 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<StepGeom_CartesianPoint, StepTidy_CartesianPointHasher>
|
||||
{
|
||||
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
|
101
src/DataExchange/TKDESTEP/StepTidy/StepTidy_CircleHasher.pxx
Normal file
101
src/DataExchange/TKDESTEP/StepTidy/StepTidy_CircleHasher.pxx
Normal file
@ -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 <StepTidy_Axis2Placement2dHasher.pxx>
|
||||
#include <StepTidy_Axis2Placement3dHasher.pxx>
|
||||
|
||||
#include <Standard_HashUtils.hxx>
|
||||
#include <StepGeom_Circle.hxx>
|
||||
#include <TCollection_HAsciiString.hxx>
|
||||
|
||||
//! 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<int>(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<TCollection_AsciiString>{}(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
|
@ -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 <StepTidy_CircleReducer.pxx>
|
||||
|
||||
#include <Interface_Graph.hxx>
|
||||
#include <StepShape_EdgeCurve.hxx>
|
||||
#include <StepGeom_SurfaceCurve.hxx>
|
||||
#include <StepGeom_SeamCurve.hxx>
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
StepTidy_CircleReducer::StepTidy_CircleReducer(const Handle(XSControl_WorkSession)& theWS)
|
||||
: StepTidy_EntityReducer<StepGeom_Circle, StepTidy_CircleHasher>(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;
|
||||
}
|
@ -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 <StepTidy_EntityReducer.pxx>
|
||||
#include <StepTidy_CircleHasher.pxx>
|
||||
|
||||
#include <StepGeom_Circle.hxx>
|
||||
|
||||
//! Processor for merging StepGeom_Circle entities.
|
||||
//! This processor merges circles with the same position and radius and names.
|
||||
class StepTidy_CircleReducer : public StepTidy_EntityReducer<StepGeom_Circle, StepTidy_CircleHasher>
|
||||
{
|
||||
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
|
@ -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 <Standard_HashUtils.hxx>
|
||||
#include <StepGeom_Direction.hxx>
|
||||
#include <TCollection_HAsciiString.hxx>
|
||||
|
||||
//! 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<int>(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<TCollection_AsciiString>{}(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
|
@ -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 <StepTidy_DirectionReducer.pxx>
|
||||
|
||||
#include <Interface_Graph.hxx>
|
||||
#include <StepGeom_Axis1Placement.hxx>
|
||||
#include <StepGeom_Axis2Placement3d.hxx>
|
||||
#include <StepGeom_Vector.hxx>
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
StepTidy_DirectionReducer::StepTidy_DirectionReducer(const Handle(XSControl_WorkSession)& theWS)
|
||||
: StepTidy_EntityReducer<StepGeom_Direction, StepTidy_DirectionHasher>(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;
|
||||
}
|
@ -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 <StepTidy_EntityReducer.pxx>
|
||||
#include <StepTidy_DirectionHasher.pxx>
|
||||
|
||||
#include <StepGeom_Direction.hxx>
|
||||
|
||||
//! 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<StepGeom_Direction, StepTidy_DirectionHasher>
|
||||
{
|
||||
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
|
123
src/DataExchange/TKDESTEP/StepTidy/StepTidy_DuplicateCleaner.cxx
Normal file
123
src/DataExchange/TKDESTEP/StepTidy/StepTidy_DuplicateCleaner.cxx
Normal file
@ -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 <StepTidy_DuplicateCleaner.hxx>
|
||||
|
||||
#include <Interface_EntityIterator.hxx>
|
||||
#include <Interface_Graph.hxx>
|
||||
#include <StepTidy_Axis2Placement3dReducer.pxx>
|
||||
#include <StepTidy_CartesianPointReducer.pxx>
|
||||
#include <StepTidy_DirectionReducer.pxx>
|
||||
#include <StepTidy_LineReducer.pxx>
|
||||
#include <StepTidy_VectorReducer.pxx>
|
||||
#include <StepTidy_PlaneReducer.pxx>
|
||||
#include <StepTidy_CircleReducer.pxx>
|
||||
#include <StepData_StepModel.hxx>
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
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();
|
||||
}
|
@ -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 <TColStd_MapOfTransient.hxx>
|
||||
|
||||
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
|
241
src/DataExchange/TKDESTEP/StepTidy/StepTidy_EntityReducer.pxx
Normal file
241
src/DataExchange/TKDESTEP/StepTidy/StepTidy_EntityReducer.pxx
Normal file
@ -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 <Interface_Graph.hxx>
|
||||
#include <NCollection_Allocator.hxx>
|
||||
#include <NCollection_DataMap.hxx>
|
||||
#include <Standard_HashUtils.hxx>
|
||||
#include <XSControl_WorkSession.hxx>
|
||||
#include <TColStd_MapOfTransient.hxx>
|
||||
|
||||
#include <functional>
|
||||
|
||||
//! 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 <typename ProcessedType, typename ProcessedTypeHasher>
|
||||
class StepTidy_EntityReducer
|
||||
{
|
||||
protected:
|
||||
// Map of duplicate entities. Key is the first processed entity, value is a list of duplicates.
|
||||
using DuplicateMap = NCollection_DataMap<Handle(ProcessedType),
|
||||
std::vector<Handle(ProcessedType)>,
|
||||
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<bool(const Handle(ProcessedType)&,
|
||||
const Handle(ProcessedType)&,
|
||||
const Handle(Standard_Transient))>;
|
||||
// Map of replacer functions. Key is the type of the sharing entity, value is the replacer
|
||||
// function for this type.
|
||||
using ReplacerMap = NCollection_DataMap<Handle(Standard_Type), ReplacerFunction>;
|
||||
|
||||
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 <typename ProcessedType, typename ProcessedTypeHasher>
|
||||
StepTidy_EntityReducer<ProcessedType, ProcessedTypeHasher>::StepTidy_EntityReducer(
|
||||
const Handle(XSControl_WorkSession)& theWS)
|
||||
: myWS(theWS),
|
||||
myReplacerMap(),
|
||||
myDuplicateMap()
|
||||
{
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
template <typename ProcessedType, typename ProcessedTypeHasher>
|
||||
bool StepTidy_EntityReducer<ProcessedType, ProcessedTypeHasher>::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<Handle(ProcessedType)>* anIter = myDuplicateMap.ChangeSeek(anEntity);
|
||||
if (anIter == nullptr)
|
||||
{
|
||||
// Add as a new key.
|
||||
myDuplicateMap.Bind(anEntity, std::vector<Handle(ProcessedType)>{});
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add as a value.
|
||||
anIter->push_back(anEntity);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
template <typename ProcessedType, typename ProcessedTypeHasher>
|
||||
void StepTidy_EntityReducer<ProcessedType, ProcessedTypeHasher>::Perform(
|
||||
TColStd_MapOfTransient& theReplacedEntities)
|
||||
{
|
||||
for (typename DuplicateMap::Iterator anIter(myDuplicateMap); anIter.More(); anIter.Next())
|
||||
{
|
||||
const Handle(ProcessedType)& anEntity = anIter.Key();
|
||||
const std::vector<Handle(ProcessedType)>& 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 <typename ProcessedType, typename ProcessedTypeHasher>
|
||||
void StepTidy_EntityReducer<ProcessedType, ProcessedTypeHasher>::registerReplacer(
|
||||
const Handle(Standard_Type)& theType,
|
||||
const ReplacerFunction& theReplacer)
|
||||
{
|
||||
myReplacerMap.Bind(theType, theReplacer);
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
template <typename ProcessedType, typename ProcessedTypeHasher>
|
||||
bool StepTidy_EntityReducer<ProcessedType, ProcessedTypeHasher>::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 <typename ProcessedType, typename ProcessedTypeHasher>
|
||||
bool StepTidy_EntityReducer<ProcessedType, ProcessedTypeHasher>::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
|
77
src/DataExchange/TKDESTEP/StepTidy/StepTidy_LineHasher.pxx
Normal file
77
src/DataExchange/TKDESTEP/StepTidy/StepTidy_LineHasher.pxx
Normal file
@ -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 <StepTidy_CartesianPointHasher.pxx>
|
||||
#include <StepTidy_VectorHasher.pxx>
|
||||
|
||||
#include <Standard_HashUtils.hxx>
|
||||
#include <StepGeom_Line.hxx>
|
||||
#include <TCollection_HAsciiString.hxx>
|
||||
|
||||
//! 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<TCollection_AsciiString>{}(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
|
117
src/DataExchange/TKDESTEP/StepTidy/StepTidy_LineReducer.cxx
Normal file
117
src/DataExchange/TKDESTEP/StepTidy/StepTidy_LineReducer.cxx
Normal file
@ -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 <StepTidy_LineReducer.pxx>
|
||||
|
||||
#include <Interface_Graph.hxx>
|
||||
#include <StepShape_EdgeCurve.hxx>
|
||||
#include <StepGeom_TrimmedCurve.hxx>
|
||||
#include <StepGeom_SurfaceCurve.hxx>
|
||||
#include <StepRepr_DefinitionalRepresentation.hxx>
|
||||
#include <StepGeom_SeamCurve.hxx>
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
StepTidy_LineReducer::StepTidy_LineReducer(const Handle(XSControl_WorkSession)& theWS)
|
||||
: StepTidy_EntityReducer<StepGeom_Line, StepTidy_LineHasher>(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;
|
||||
}
|
83
src/DataExchange/TKDESTEP/StepTidy/StepTidy_LineReducer.pxx
Normal file
83
src/DataExchange/TKDESTEP/StepTidy/StepTidy_LineReducer.pxx
Normal file
@ -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 <StepTidy_EntityReducer.pxx>
|
||||
#include <StepTidy_LineHasher.pxx>
|
||||
|
||||
#include <StepGeom_Line.hxx>
|
||||
|
||||
//! Processor for merging StepGeom_Line entities.
|
||||
//! This processor merges lines with the same point and direction and names.
|
||||
class StepTidy_LineReducer : public StepTidy_EntityReducer<StepGeom_Line, StepTidy_LineHasher>
|
||||
{
|
||||
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
|
60
src/DataExchange/TKDESTEP/StepTidy/StepTidy_PlaneHasher.pxx
Normal file
60
src/DataExchange/TKDESTEP/StepTidy/StepTidy_PlaneHasher.pxx
Normal file
@ -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 <StepTidy_Axis2Placement3dHasher.pxx>
|
||||
|
||||
#include <Standard_HashUtils.hxx>
|
||||
#include <StepGeom_Plane.hxx>
|
||||
|
||||
//! 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<TCollection_AsciiString>{}(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
|
55
src/DataExchange/TKDESTEP/StepTidy/StepTidy_PlaneReducer.cxx
Normal file
55
src/DataExchange/TKDESTEP/StepTidy/StepTidy_PlaneReducer.cxx
Normal file
@ -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 <StepTidy_PlaneReducer.pxx>
|
||||
|
||||
#include <StepShape_AdvancedFace.hxx>
|
||||
#include <StepGeom_Pcurve.hxx>
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
StepTidy_PlaneReducer::StepTidy_PlaneReducer(const Handle(XSControl_WorkSession)& theWS)
|
||||
: StepTidy_EntityReducer<StepGeom_Plane, StepTidy_PlaneHasher>(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;
|
||||
}
|
53
src/DataExchange/TKDESTEP/StepTidy/StepTidy_PlaneReducer.pxx
Normal file
53
src/DataExchange/TKDESTEP/StepTidy/StepTidy_PlaneReducer.pxx
Normal file
@ -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 <StepTidy_EntityReducer.pxx>
|
||||
#include <StepTidy_PlaneHasher.pxx>
|
||||
|
||||
#include <StepGeom_Plane.hxx>
|
||||
|
||||
//! Processor for merging StepGeom_Plane entities.
|
||||
//! This processor merges planes with the same names and placements.
|
||||
class StepTidy_PlaneReducer : public StepTidy_EntityReducer<StepGeom_Plane, StepTidy_PlaneHasher>
|
||||
{
|
||||
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
|
70
src/DataExchange/TKDESTEP/StepTidy/StepTidy_VectorHasher.pxx
Normal file
70
src/DataExchange/TKDESTEP/StepTidy/StepTidy_VectorHasher.pxx
Normal file
@ -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 <StepTidy_DirectionHasher.pxx>
|
||||
|
||||
#include <Standard_HashUtils.hxx>
|
||||
#include <StepGeom_Vector.hxx>
|
||||
#include <TCollection_HAsciiString.hxx>
|
||||
|
||||
//! 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<int>(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<TCollection_AsciiString>{}(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
|
@ -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 <StepTidy_VectorReducer.pxx>
|
||||
|
||||
#include <Interface_Graph.hxx>
|
||||
#include <StepGeom_Line.hxx>
|
||||
#include <StepGeom_Vector.hxx>
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
StepTidy_VectorReducer::StepTidy_VectorReducer(const Handle(XSControl_WorkSession)& theWS)
|
||||
: StepTidy_EntityReducer<StepGeom_Vector, StepTidy_VectorHasher>(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;
|
||||
}
|
@ -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 <StepTidy_EntityReducer.pxx>
|
||||
#include <StepTidy_VectorHasher.pxx>
|
||||
|
||||
#include <StepGeom_Vector.hxx>
|
||||
|
||||
//! Processor for merging StepGeom_Vector entities.
|
||||
//! This processor merges vectors with the same orientation and magnitude and names.
|
||||
class StepTidy_VectorReducer : public StepTidy_EntityReducer<StepGeom_Vector, StepTidy_VectorHasher>
|
||||
{
|
||||
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
|
@ -195,6 +195,7 @@ provider.STEP.OCC.write.name : 1
|
||||
provider.STEP.OCC.write.layer : 1
|
||||
provider.STEP.OCC.write.props : 1
|
||||
provider.STEP.OCC.write.model.type : 0
|
||||
provider.STEP.OCC.write.cleanduplicates : 0
|
||||
provider.STEP.OCC.healing.tolerance3d : 1e-06
|
||||
provider.STEP.OCC.healing.max.tolerance3d : 1
|
||||
provider.STEP.OCC.healing.min.tolerance3d : 1e-07
|
||||
|
@ -140,6 +140,7 @@ provider.STEP.OCC.write.name : 1
|
||||
provider.STEP.OCC.write.layer : 1
|
||||
provider.STEP.OCC.write.props : 1
|
||||
provider.STEP.OCC.write.model.type : 0
|
||||
provider.STEP.OCC.write.cleanduplicates : 0
|
||||
provider.STEP.OCC.healing.tolerance3d : 1e-06
|
||||
provider.STEP.OCC.healing.max.tolerance3d : 1
|
||||
provider.STEP.OCC.healing.min.tolerance3d : 1e-07
|
||||
|
Loading…
x
Reference in New Issue
Block a user