| | |
| |
|
| | #include <gtest/gtest.h> |
| | #include <Mod/Part/App/TopoShape.h> |
| | #include <Mod/Part/App/TopoShapeCache.h> |
| |
|
| | #include <src/App/InitApplication.h> |
| | #include <gp_Quaternion.hxx> |
| | #include <TopoDS_TVertex.hxx> |
| | #include <BRep_TVertex.hxx> |
| | #include <BRepBuilderAPI_MakeEdge.hxx> |
| | #include <BRepAlgoAPI_Fuse.hxx> |
| | #include <BRepPrimAPI_MakeBox.hxx> |
| | #include <TopoDS_Edge.hxx> |
| |
|
| | |
| |
|
| | class ShapeRelationKey: public ::testing::Test |
| | { |
| | protected: |
| | static void SetUpTestSuite() |
| | { |
| | tests::initApplication(); |
| | } |
| | }; |
| |
|
| | TEST_F(ShapeRelationKey, HistoryTraceTypeComparison) |
| | { |
| | |
| | Data::MappedName mappedName {"mappedName"}; |
| | Part::HistoryTraceType htt1 {Part::HistoryTraceType::stopOnTypeChange}; |
| | Part::HistoryTraceType htt2 {Part::HistoryTraceType::followTypeChange}; |
| | Part::ShapeRelationKey key1 {mappedName, htt1}; |
| | Part::ShapeRelationKey key2 {mappedName, htt2}; |
| |
|
| | |
| | bool key1LessThanKey2 = key1 < key2; |
| |
|
| | |
| | ASSERT_TRUE(key1LessThanKey2); |
| | } |
| |
|
| | class TopoShapeCacheTest: public ::testing::Test |
| | { |
| | protected: |
| | static void SetUpTestSuite() |
| | { |
| | tests::initApplication(); |
| | } |
| |
|
| | void SetUp() override |
| | { |
| | _docName = App::GetApplication().getUniqueDocumentName("test"); |
| | App::GetApplication().newDocument(_docName.c_str(), "testUser"); |
| | _sids = &_sid; |
| | _hasher = Base::Reference<App::StringHasher>(new App::StringHasher); |
| | ASSERT_EQ(_hasher.getRefCount(), 1); |
| | } |
| |
|
| | void TearDown() override |
| | { |
| | App::GetApplication().closeDocument(_docName.c_str()); |
| | } |
| |
|
| | private: |
| | std::string _docName; |
| | Data::ElementIDRefs _sid; |
| | QVector<App::StringIDRef>* _sids = nullptr; |
| | App::StringHasherRef _hasher; |
| | }; |
| |
|
| | TEST_F(TopoShapeCacheTest, ConstructionFromTopoDS_Shape) |
| | { |
| | |
| | TopoDS_Vertex vertex; |
| | gp_Quaternion quaternion(1.0, 2.0, 3.0, 4.0); |
| | gp_Trsf transform; |
| | transform.SetRotation(quaternion); |
| | auto location = TopLoc_Location(transform); |
| | vertex.Location(location); |
| |
|
| | |
| | auto cache = Part::TopoShapeCache(vertex); |
| |
|
| | |
| | EXPECT_NE(cache.shape.Location(), vertex.Location()); |
| | } |
| |
|
| | TEST_F(TopoShapeCacheTest, InsertRelationIntoEmptyTableCompacts) |
| | { |
| | |
| | Data::IndexedName indexedName {"EDGE1"}; |
| | auto mappedName = Data::MappedName::fromRawData("#94;:G0;XTR;:H19:8,F;:H1a,F;BND:-1:0;:H1b:10,F"); |
| | ASSERT_TRUE(mappedName.isRaw()); |
| | Data::MappedElement mappedElement1 {indexedName, mappedName}; |
| | QVector<Data::MappedElement> vectorOfElements {mappedElement1}; |
| | TopoDS_Vertex vertex; |
| | Part::TopoShapeCache cache(vertex); |
| | Part::ShapeRelationKey key {mappedName, Part::HistoryTraceType::followTypeChange}; |
| |
|
| | |
| | cache.insertRelation(key, vectorOfElements); |
| |
|
| | |
| | auto foundIterator = cache.relations.find(key); |
| | EXPECT_NE(foundIterator, cache.relations.end()); |
| | EXPECT_FALSE(foundIterator->first.name.isRaw()); |
| | } |
| |
|
| | TEST_F(TopoShapeCacheTest, InsertAlreadyExistsUpdatesExisting) |
| | { |
| | |
| | Data::IndexedName indexedName {"EDGE1"}; |
| | Data::MappedName mappedName("#94;:G0;XTR;:H19:8,F;:H1a,F;BND:-1:0;:H1b:10,F"); |
| | Data::MappedElement mappedElement1 {indexedName, mappedName}; |
| | QVector<Data::MappedElement> vectorOfElements {mappedElement1}; |
| | TopoDS_Vertex vertex; |
| | Part::TopoShapeCache cache(vertex); |
| | Part::ShapeRelationKey key {mappedName, Part::HistoryTraceType::followTypeChange}; |
| |
|
| | |
| | cache.insertRelation(key, vectorOfElements); |
| | QVector<Data::MappedElement> emptyVector; |
| | cache.insertRelation(key, emptyVector); |
| |
|
| | |
| | EXPECT_TRUE(cache.relations.find(key)->second.empty()); |
| | } |
| |
|
| | TEST_F(TopoShapeCacheTest, IsTouchedNotPartners) |
| | { |
| | |
| | BRep_TVertex* vertex1 = new BRep_TVertex; |
| | vertex1->Pnt(gp_Pnt(1.0, 1.0, 1.0)); |
| | BRep_TVertex* vertex2 = new BRep_TVertex; |
| | vertex2->Pnt(gp_Pnt(2.0, 2.0, 2.0)); |
| | opencascade::handle<TopoDS_TShape> handle1(vertex1); |
| | opencascade::handle<TopoDS_TShape> handle2(vertex2); |
| | TopoDS_Vertex tds1; |
| | TopoDS_Vertex tds2; |
| | tds1.TShape(handle1); |
| | tds2.TShape(handle2); |
| | ASSERT_FALSE(tds1.IsPartner(tds2)); |
| | Part::TopoShapeCache cache(tds1); |
| |
|
| | |
| | EXPECT_TRUE(cache.isTouched(tds2)); |
| | } |
| |
|
| | TEST_F(TopoShapeCacheTest, IsTouchedArePartners) |
| | { |
| | |
| | BRep_TVertex* vertex1 = new BRep_TVertex; |
| | vertex1->Pnt(gp_Pnt(1.0, 1.0, 1.0)); |
| | opencascade::handle<TopoDS_TShape> handle1(vertex1); |
| | TopoDS_Vertex tds1; |
| | TopoDS_Vertex tds2; |
| | tds1.TShape(handle1); |
| | tds2.TShape(handle1); |
| | ASSERT_TRUE(tds1.IsPartner(tds2)); |
| | Part::TopoShapeCache cache(tds1); |
| |
|
| | |
| | EXPECT_FALSE(cache.isTouched(tds2)); |
| | } |
| |
|
| | std::tuple<TopoDS_Shape, std::pair<TopoDS_Shape, TopoDS_Shape>> CreateShapeWithSubshapes() |
| | { |
| | auto edge1 = BRepBuilderAPI_MakeEdge(gp_Pnt(0.0, 0.0, 0.0), gp_Pnt(1.0, 0.0, 0.0)).Edge(); |
| | auto edge2 = BRepBuilderAPI_MakeEdge(gp_Pnt(1.0, 0.0, 0.0), gp_Pnt(2.0, 0.0, 0.0)).Edge(); |
| | auto fuse = BRepAlgoAPI_Fuse(edge1, edge2); |
| | fuse.Build(); |
| | return {fuse.Shape(), {edge1, edge2}}; |
| | } |
| |
|
| | TEST_F(TopoShapeCacheTest, GetAncestrySHAPE) |
| | { |
| | |
| | auto shape = std::get<0>(CreateShapeWithSubshapes()); |
| | Part::TopoShapeCache cache(shape); |
| |
|
| | |
| | auto ancestry = cache.getAncestry(TopAbs_SHAPE); |
| |
|
| | |
| | EXPECT_EQ(2, ancestry.count()); |
| | } |
| |
|
| | TEST_F(TopoShapeCacheTest, GetAncestryEDGE) |
| | { |
| | |
| | auto shape = std::get<0>(CreateShapeWithSubshapes()); |
| | Part::TopoShapeCache cache(shape); |
| |
|
| | |
| | auto ancestry = cache.getAncestry(TopAbs_EDGE); |
| |
|
| | |
| | EXPECT_EQ(2, ancestry.count()); |
| | } |
| |
|
| | TEST_F(TopoShapeCacheTest, GetAncestryFACE) |
| | { |
| | |
| | auto shape = std::get<0>(CreateShapeWithSubshapes()); |
| | Part::TopoShapeCache cache(shape); |
| |
|
| | |
| | auto ancestry = cache.getAncestry(TopAbs_FACE); |
| |
|
| | |
| | EXPECT_EQ(0, ancestry.count()); |
| | } |
| |
|
| | TEST_F(TopoShapeCacheTest, CountShape) |
| | { |
| | |
| | auto shape = std::get<0>(CreateShapeWithSubshapes()); |
| | Part::TopoShapeCache cache(shape); |
| |
|
| | |
| | int countOfEdges = cache.countShape(TopAbs_EDGE); |
| | int countOfFaces = cache.countShape(TopAbs_FACE); |
| | int countOfShapes = cache.countShape(TopAbs_SHAPE); |
| |
|
| | |
| | EXPECT_EQ(2, countOfEdges); |
| | EXPECT_EQ(0, countOfFaces); |
| | EXPECT_EQ(2, countOfShapes); |
| | } |
| |
|
| | TEST_F(TopoShapeCacheTest, FindShapeGivenSubshape) |
| | { |
| | |
| | const auto [shape, ancestors] = CreateShapeWithSubshapes(); |
| | Part::TopoShapeCache cache(shape); |
| |
|
| | |
| | auto shapeResult1 = cache.findShape(ancestors.first, shape); |
| | auto shapeResult2 = cache.findShape(ancestors.second, shape); |
| |
|
| | |
| | EXPECT_NE(0, shapeResult1); |
| | EXPECT_NE(0, shapeResult2); |
| | } |
| |
|
| | TEST_F(TopoShapeCacheTest, FindShapeGivenTypeAndIndex) |
| | { |
| | |
| | const auto [shape, ancestors] = CreateShapeWithSubshapes(); |
| | Part::TopoShapeCache cache(shape); |
| |
|
| | |
| | auto shapeResult = cache.findShape(ancestors.first, TopAbs_EDGE, 1); |
| |
|
| | |
| | EXPECT_FALSE(shapeResult.IsNull()); |
| | } |
| |
|
| | std::tuple<TopoDS_Shape, std::pair<TopoDS_Shape, TopoDS_Shape>> CreateFusedCubes() |
| | { |
| | auto boxMaker1 = BRepPrimAPI_MakeBox(1.0, 1.0, 1.0); |
| | boxMaker1.Build(); |
| | auto box1 = boxMaker1.Shape(); |
| |
|
| | auto boxMaker2 = BRepPrimAPI_MakeBox(1.0, 1.0, 1.0); |
| | boxMaker2.Build(); |
| | auto box2 = boxMaker2.Shape(); |
| | auto transform = gp_Trsf(); |
| | transform.SetTranslation(gp_Pnt(0.0, 0.0, 0.0), gp_Pnt(1.0, 0.0, 0.0)); |
| | box2.Location(TopLoc_Location(transform)); |
| |
|
| | auto fuse = BRepAlgoAPI_Fuse(box1, box2); |
| | fuse.Build(); |
| |
|
| | return {fuse, {box1, box2}}; |
| | } |
| |
|
| | TEST_F(TopoShapeCacheTest, FindAncestor) |
| | { |
| | |
| | const auto [shape, ancestors] = CreateFusedCubes(); |
| | Part::TopoShapeCache cache(shape); |
| |
|
| | |
| | auto ancestorResultCompound = cache.findAncestor(ancestors.first, shape, TopAbs_COMPOUND); |
| |
|
| | |
| | EXPECT_FALSE(ancestorResultCompound.IsNull()); |
| | } |
| |
|
| | |
| |
|