Foundation Classes - Refactor TShape hierarchy for performance and memory efficiency (#1027)

- Made ShapeType() non-virtual by embedding the shape type in a compact uint16_t state field alongside flags
- Replaced int myFlags with uint16_t myState using a BitLayout enum for compact storage
- Moved Compose/Reverse/Complement operations from TopAbs.cxx to inline implementations in TopAbs.hxx
- Updated all TShape derived class constructors to pass their type to the base class
- Refactored TopoDS_Iterator to use index-based iteration with updateCurrentShape() helper
This commit is contained in:
Pasukhin Dmitry
2026-01-23 21:08:39 +00:00
committed by GitHub
parent 09996b852b
commit 3aeb4668f5
28 changed files with 1494 additions and 272 deletions

View File

@@ -3,6 +3,8 @@ set(OCCT_TKBRep_GTests_FILES_LOCATION "${CMAKE_CURRENT_LIST_DIR}")
set(OCCT_TKBRep_GTests_FILES
BRepAdaptor_CompCurve_Test.cxx
TopoDS_Builder_Test.cxx
TopoDS_Edge_Test.cxx
TopoDS_Iterator_Test.cxx
TopoDS_TShape_Test.cxx
)

View File

@@ -0,0 +1,547 @@
// Copyright (c) 2026 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 <gtest/gtest.h>
#include <BRep_Builder.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeVertex.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Builder.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_CompSolid.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopoDS_Shell.hxx>
#include <TopoDS_Solid.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Wire.hxx>
#include <gp_Pnt.hxx>
//==================================================================================================
// Test TopoDS_Builder::MakeWire
//==================================================================================================
TEST(TopoDS_Builder_Test, MakeWire)
{
TopoDS_Builder aBuilder;
TopoDS_Wire aWire;
aBuilder.MakeWire(aWire);
EXPECT_FALSE(aWire.IsNull()) << "Wire should not be null after MakeWire";
EXPECT_EQ(aWire.ShapeType(), TopAbs_WIRE) << "Shape type should be WIRE";
EXPECT_TRUE(aWire.Free()) << "Newly created wire should be free";
}
//==================================================================================================
// Test TopoDS_Builder::MakeShell
//==================================================================================================
TEST(TopoDS_Builder_Test, MakeShell)
{
TopoDS_Builder aBuilder;
TopoDS_Shell aShell;
aBuilder.MakeShell(aShell);
EXPECT_FALSE(aShell.IsNull()) << "Shell should not be null";
EXPECT_EQ(aShell.ShapeType(), TopAbs_SHELL);
}
//==================================================================================================
// Test TopoDS_Builder::MakeSolid
//==================================================================================================
TEST(TopoDS_Builder_Test, MakeSolid)
{
TopoDS_Builder aBuilder;
TopoDS_Solid aSolid;
aBuilder.MakeSolid(aSolid);
EXPECT_FALSE(aSolid.IsNull()) << "Solid should not be null";
EXPECT_EQ(aSolid.ShapeType(), TopAbs_SOLID);
}
//==================================================================================================
// Test TopoDS_Builder::MakeCompSolid
//==================================================================================================
TEST(TopoDS_Builder_Test, MakeCompSolid)
{
TopoDS_Builder aBuilder;
TopoDS_CompSolid aCompSolid;
aBuilder.MakeCompSolid(aCompSolid);
EXPECT_FALSE(aCompSolid.IsNull()) << "CompSolid should not be null";
EXPECT_EQ(aCompSolid.ShapeType(), TopAbs_COMPSOLID);
}
//==================================================================================================
// Test TopoDS_Builder::MakeCompound
//==================================================================================================
TEST(TopoDS_Builder_Test, MakeCompound)
{
TopoDS_Builder aBuilder;
TopoDS_Compound aCompound;
aBuilder.MakeCompound(aCompound);
EXPECT_FALSE(aCompound.IsNull()) << "Compound should not be null";
EXPECT_EQ(aCompound.ShapeType(), TopAbs_COMPOUND);
}
//==================================================================================================
// Test TopoDS_Builder::Add - add vertices to compound
//==================================================================================================
TEST(TopoDS_Builder_Test, Add_VerticesToCompound)
{
TopoDS_Builder aBuilder;
TopoDS_Compound aCompound;
aBuilder.MakeCompound(aCompound);
// Create and add vertices
TopoDS_Vertex aV1 = BRepBuilderAPI_MakeVertex(gp_Pnt(0, 0, 0));
TopoDS_Vertex aV2 = BRepBuilderAPI_MakeVertex(gp_Pnt(1, 0, 0));
TopoDS_Vertex aV3 = BRepBuilderAPI_MakeVertex(gp_Pnt(0, 1, 0));
aBuilder.Add(aCompound, aV1);
aBuilder.Add(aCompound, aV2);
aBuilder.Add(aCompound, aV3);
// Count children using iterator
int aCount = 0;
for (TopoDS_Iterator anIt(aCompound); anIt.More(); anIt.Next())
{
++aCount;
}
EXPECT_EQ(aCount, 3) << "Compound should have 3 vertices";
}
//==================================================================================================
// Test TopoDS_Builder::Add - add edges to wire
//==================================================================================================
TEST(TopoDS_Builder_Test, Add_EdgesToWire)
{
TopoDS_Builder aBuilder;
TopoDS_Wire aWire;
aBuilder.MakeWire(aWire);
// Create edges forming a triangle
TopoDS_Edge aE1 = BRepBuilderAPI_MakeEdge(gp_Pnt(0, 0, 0), gp_Pnt(1, 0, 0));
TopoDS_Edge aE2 = BRepBuilderAPI_MakeEdge(gp_Pnt(1, 0, 0), gp_Pnt(0.5, 1, 0));
TopoDS_Edge aE3 = BRepBuilderAPI_MakeEdge(gp_Pnt(0.5, 1, 0), gp_Pnt(0, 0, 0));
aBuilder.Add(aWire, aE1);
aBuilder.Add(aWire, aE2);
aBuilder.Add(aWire, aE3);
// Count children
int aCount = 0;
for (TopoDS_Iterator anIt(aWire); anIt.More(); anIt.Next())
{
EXPECT_EQ(anIt.Value().ShapeType(), TopAbs_EDGE);
++aCount;
}
EXPECT_EQ(aCount, 3) << "Wire should have 3 edges";
}
//==================================================================================================
// Test TopoDS_Builder::Remove
//==================================================================================================
TEST(TopoDS_Builder_Test, Remove_FromCompound)
{
TopoDS_Builder aBuilder;
TopoDS_Compound aCompound;
aBuilder.MakeCompound(aCompound);
// Add vertices
TopoDS_Vertex aV1 = BRepBuilderAPI_MakeVertex(gp_Pnt(0, 0, 0));
TopoDS_Vertex aV2 = BRepBuilderAPI_MakeVertex(gp_Pnt(1, 0, 0));
TopoDS_Vertex aV3 = BRepBuilderAPI_MakeVertex(gp_Pnt(0, 1, 0));
aBuilder.Add(aCompound, aV1);
aBuilder.Add(aCompound, aV2);
aBuilder.Add(aCompound, aV3);
// Remove middle vertex
aBuilder.Remove(aCompound, aV2);
// Count remaining children
int aCount = 0;
for (TopoDS_Iterator anIt(aCompound); anIt.More(); anIt.Next())
{
++aCount;
}
EXPECT_EQ(aCount, 2) << "Compound should have 2 vertices after removal";
}
//==================================================================================================
// Test adding many shapes to compound
//==================================================================================================
TEST(TopoDS_Builder_Test, Add_ManyShapes)
{
TopoDS_Builder aBuilder;
TopoDS_Compound aCompound;
aBuilder.MakeCompound(aCompound);
// Add 500 vertices
for (int i = 0; i < 500; ++i)
{
TopoDS_Vertex aV = BRepBuilderAPI_MakeVertex(gp_Pnt(i, 0, 0));
aBuilder.Add(aCompound, aV);
}
// Verify count
int aCount = 0;
for (TopoDS_Iterator anIt(aCompound); anIt.More(); anIt.Next())
{
++aCount;
}
EXPECT_EQ(aCount, 500) << "Compound should have 500 vertices";
}
//==================================================================================================
// Test TShape flags through shape interface
//==================================================================================================
TEST(TopoDS_Builder_Test, TShapeFlags)
{
TopoDS_Builder aBuilder;
TopoDS_Compound aCompound;
aBuilder.MakeCompound(aCompound);
// Test initial flags
EXPECT_TRUE(aCompound.Free()) << "New shape should be free";
EXPECT_TRUE(aCompound.Modified()) << "New shape should be modified";
// Test setting flags
aCompound.Checked(true);
EXPECT_TRUE(aCompound.Checked());
aCompound.Closed(true);
EXPECT_TRUE(aCompound.Closed());
aCompound.Infinite(true);
EXPECT_TRUE(aCompound.Infinite());
aCompound.Convex(true);
EXPECT_TRUE(aCompound.Convex());
}
//==================================================================================================
// Test TopoDS_Builder::Remove first child
//==================================================================================================
TEST(TopoDS_Builder_Test, Remove_FirstChild)
{
TopoDS_Builder aBuilder;
TopoDS_Compound aCompound;
aBuilder.MakeCompound(aCompound);
TopoDS_Vertex aV1 = BRepBuilderAPI_MakeVertex(gp_Pnt(1, 0, 0));
TopoDS_Vertex aV2 = BRepBuilderAPI_MakeVertex(gp_Pnt(2, 0, 0));
TopoDS_Vertex aV3 = BRepBuilderAPI_MakeVertex(gp_Pnt(3, 0, 0));
aBuilder.Add(aCompound, aV1);
aBuilder.Add(aCompound, aV2);
aBuilder.Add(aCompound, aV3);
// Remove first vertex
aBuilder.Remove(aCompound, aV1);
// Should have 2 remaining
int aCount = 0;
for (TopoDS_Iterator anIt(aCompound); anIt.More(); anIt.Next())
{
++aCount;
}
EXPECT_EQ(aCount, 2);
}
//==================================================================================================
// Test TopoDS_Builder::Remove last child
//==================================================================================================
TEST(TopoDS_Builder_Test, Remove_LastChild)
{
TopoDS_Builder aBuilder;
TopoDS_Compound aCompound;
aBuilder.MakeCompound(aCompound);
TopoDS_Vertex aV1 = BRepBuilderAPI_MakeVertex(gp_Pnt(1, 0, 0));
TopoDS_Vertex aV2 = BRepBuilderAPI_MakeVertex(gp_Pnt(2, 0, 0));
TopoDS_Vertex aV3 = BRepBuilderAPI_MakeVertex(gp_Pnt(3, 0, 0));
aBuilder.Add(aCompound, aV1);
aBuilder.Add(aCompound, aV2);
aBuilder.Add(aCompound, aV3);
// Remove last vertex
aBuilder.Remove(aCompound, aV3);
// Should have 2 remaining
int aCount = 0;
for (TopoDS_Iterator anIt(aCompound); anIt.More(); anIt.Next())
{
++aCount;
}
EXPECT_EQ(aCount, 2);
}
//==================================================================================================
// Test TopoDS_Builder::Remove all children one by one
//==================================================================================================
TEST(TopoDS_Builder_Test, Remove_AllChildren)
{
TopoDS_Builder aBuilder;
TopoDS_Compound aCompound;
aBuilder.MakeCompound(aCompound);
TopoDS_Vertex aV1 = BRepBuilderAPI_MakeVertex(gp_Pnt(1, 0, 0));
TopoDS_Vertex aV2 = BRepBuilderAPI_MakeVertex(gp_Pnt(2, 0, 0));
TopoDS_Vertex aV3 = BRepBuilderAPI_MakeVertex(gp_Pnt(3, 0, 0));
aBuilder.Add(aCompound, aV1);
aBuilder.Add(aCompound, aV2);
aBuilder.Add(aCompound, aV3);
// Remove all
aBuilder.Remove(aCompound, aV1);
aBuilder.Remove(aCompound, aV2);
aBuilder.Remove(aCompound, aV3);
// Should be empty
TopoDS_Iterator anIt(aCompound);
EXPECT_FALSE(anIt.More()) << "Compound should be empty after removing all children";
}
//==================================================================================================
// Test TopoDS_Builder::Remove from wire
//==================================================================================================
TEST(TopoDS_Builder_Test, Remove_FromWire)
{
TopoDS_Builder aBuilder;
TopoDS_Wire aWire;
aBuilder.MakeWire(aWire);
TopoDS_Edge aE1 = BRepBuilderAPI_MakeEdge(gp_Pnt(0, 0, 0), gp_Pnt(1, 0, 0));
TopoDS_Edge aE2 = BRepBuilderAPI_MakeEdge(gp_Pnt(1, 0, 0), gp_Pnt(1, 1, 0));
TopoDS_Edge aE3 = BRepBuilderAPI_MakeEdge(gp_Pnt(1, 1, 0), gp_Pnt(0, 0, 0));
aBuilder.Add(aWire, aE1);
aBuilder.Add(aWire, aE2);
aBuilder.Add(aWire, aE3);
// Remove middle edge
aBuilder.Remove(aWire, aE2);
// Should have 2 edges
int aCount = 0;
for (TopoDS_Iterator anIt(aWire); anIt.More(); anIt.Next())
{
++aCount;
}
EXPECT_EQ(aCount, 2);
}
//==================================================================================================
// Test TopoDS_Builder with nested compounds
//==================================================================================================
TEST(TopoDS_Builder_Test, NestedCompounds)
{
TopoDS_Builder aBuilder;
TopoDS_Compound aOuter, aInner;
aBuilder.MakeCompound(aOuter);
aBuilder.MakeCompound(aInner);
// Add vertices to inner
aBuilder.Add(aInner, BRepBuilderAPI_MakeVertex(gp_Pnt(0, 0, 0)));
aBuilder.Add(aInner, BRepBuilderAPI_MakeVertex(gp_Pnt(1, 0, 0)));
// Add inner to outer
aBuilder.Add(aOuter, aInner);
// Outer should have 1 child (the inner compound)
int aOuterCount = 0;
for (TopoDS_Iterator anIt(aOuter); anIt.More(); anIt.Next())
{
EXPECT_EQ(anIt.Value().ShapeType(), TopAbs_COMPOUND);
++aOuterCount;
}
EXPECT_EQ(aOuterCount, 1);
// Inner should still have 2 vertices
EXPECT_EQ(aInner.TShape()->NbChildren(), 2);
}
//==================================================================================================
// Test TopoDS_Builder::Add sets Modified flag
//==================================================================================================
TEST(TopoDS_Builder_Test, Add_SetsModifiedFlag)
{
TopoDS_Builder aBuilder;
TopoDS_Compound aCompound;
aBuilder.MakeCompound(aCompound);
// Clear modified flag
aCompound.TShape()->Modified(false);
EXPECT_FALSE(aCompound.Modified());
// Add should set modified
aBuilder.Add(aCompound, BRepBuilderAPI_MakeVertex(gp_Pnt(0, 0, 0)));
EXPECT_TRUE(aCompound.Modified()) << "Add should set Modified flag";
}
//==================================================================================================
// Test TopoDS_Builder::Remove sets Modified flag
//==================================================================================================
TEST(TopoDS_Builder_Test, Remove_SetsModifiedFlag)
{
TopoDS_Builder aBuilder;
TopoDS_Compound aCompound;
aBuilder.MakeCompound(aCompound);
TopoDS_Vertex aV = BRepBuilderAPI_MakeVertex(gp_Pnt(0, 0, 0));
aBuilder.Add(aCompound, aV);
// Clear modified flag
aCompound.TShape()->Modified(false);
EXPECT_FALSE(aCompound.Modified());
// Remove should set modified
aBuilder.Remove(aCompound, aV);
EXPECT_TRUE(aCompound.Modified()) << "Remove should set Modified flag";
}
//==================================================================================================
// Test all shape types
//==================================================================================================
TEST(TopoDS_Builder_Test, AllTypes)
{
TopoDS_Builder aBuilder;
// Wire
TopoDS_Wire aWire;
aBuilder.MakeWire(aWire);
EXPECT_FALSE(aWire.IsNull());
EXPECT_EQ(aWire.ShapeType(), TopAbs_WIRE);
EXPECT_TRUE(aWire.Free());
// Shell
TopoDS_Shell aShell;
aBuilder.MakeShell(aShell);
EXPECT_FALSE(aShell.IsNull());
EXPECT_EQ(aShell.ShapeType(), TopAbs_SHELL);
EXPECT_TRUE(aShell.Free());
// Solid
TopoDS_Solid aSolid;
aBuilder.MakeSolid(aSolid);
EXPECT_FALSE(aSolid.IsNull());
EXPECT_EQ(aSolid.ShapeType(), TopAbs_SOLID);
EXPECT_TRUE(aSolid.Free());
// CompSolid
TopoDS_CompSolid aCompSolid;
aBuilder.MakeCompSolid(aCompSolid);
EXPECT_FALSE(aCompSolid.IsNull());
EXPECT_EQ(aCompSolid.ShapeType(), TopAbs_COMPSOLID);
EXPECT_TRUE(aCompSolid.Free());
// Compound
TopoDS_Compound aCompound;
aBuilder.MakeCompound(aCompound);
EXPECT_FALSE(aCompound.IsNull());
EXPECT_EQ(aCompound.ShapeType(), TopAbs_COMPOUND);
EXPECT_TRUE(aCompound.Free());
}
//==================================================================================================
// Test mixed shapes in compound
//==================================================================================================
TEST(TopoDS_Builder_Test, MixedShapesInCompound)
{
TopoDS_Builder aBuilder;
TopoDS_Compound aCompound;
aBuilder.MakeCompound(aCompound);
// Add different shape types
aBuilder.Add(aCompound, BRepBuilderAPI_MakeVertex(gp_Pnt(0, 0, 0)));
aBuilder.Add(aCompound, BRepBuilderAPI_MakeEdge(gp_Pnt(0, 0, 0), gp_Pnt(1, 0, 0)));
TopoDS_Wire aWire;
aBuilder.MakeWire(aWire);
aBuilder.Add(aCompound, aWire);
TopoDS_Shell aShell;
aBuilder.MakeShell(aShell);
aBuilder.Add(aCompound, aShell);
TopoDS_Compound aInner;
aBuilder.MakeCompound(aInner);
aBuilder.Add(aCompound, aInner);
EXPECT_EQ(aCompound.TShape()->NbChildren(), 5);
// Verify types via iteration
int aVertexCount = 0, aEdgeCount = 0, aWireCount = 0, aShellCount = 0, aCompoundCount = 0;
for (TopoDS_Iterator anIt(aCompound); anIt.More(); anIt.Next())
{
switch (anIt.Value().ShapeType())
{
case TopAbs_VERTEX:
++aVertexCount;
break;
case TopAbs_EDGE:
++aEdgeCount;
break;
case TopAbs_WIRE:
++aWireCount;
break;
case TopAbs_SHELL:
++aShellCount;
break;
case TopAbs_COMPOUND:
++aCompoundCount;
break;
default:
break;
}
}
EXPECT_EQ(aVertexCount, 1);
EXPECT_EQ(aEdgeCount, 1);
EXPECT_EQ(aWireCount, 1);
EXPECT_EQ(aShellCount, 1);
EXPECT_EQ(aCompoundCount, 1);
}

View File

@@ -11,10 +11,33 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <gtest/gtest.h>
#include <BRep_Builder.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRepBuilderAPI_MakeVertex.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
#include <gp_Pnt.hxx>
#include <gp_Trsf.hxx>
#include <gp_Vec.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Builder.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Shell.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Wire.hxx>
#include <TopExp_Explorer.hxx>
#include <TopLoc_Location.hxx>
#include <gtest/gtest.h>
//=================================================================================================
// Test OCC30708_1: Initialize with null shape
//=================================================================================================
TEST(TopoDS_Iterator_Test, OCC30708_1_InitializeWithNullShape)
{
@@ -27,3 +50,418 @@ TEST(TopoDS_Iterator_Test, OCC30708_1_InitializeWithNullShape)
// More() should return false on null shape
EXPECT_FALSE(it.More());
}
//=================================================================================================
// Test iterator on empty compound
//=================================================================================================
TEST(TopoDS_Iterator_Test, EmptyCompound)
{
TopoDS_Builder aBuilder;
TopoDS_Compound aCompound;
aBuilder.MakeCompound(aCompound);
TopoDS_Iterator anIt(aCompound);
EXPECT_FALSE(anIt.More()) << "Empty compound should have no children";
}
//=================================================================================================
// Test iterator on compound with vertices
//=================================================================================================
TEST(TopoDS_Iterator_Test, CompoundWithVertices)
{
TopoDS_Builder aBuilder;
TopoDS_Compound aCompound;
aBuilder.MakeCompound(aCompound);
// Add 5 vertices
for (int i = 0; i < 5; ++i)
{
TopoDS_Vertex aV = BRepBuilderAPI_MakeVertex(gp_Pnt(i, 0, 0));
aBuilder.Add(aCompound, aV);
}
// Iterate and count
int aCount = 0;
for (TopoDS_Iterator anIt(aCompound); anIt.More(); anIt.Next())
{
EXPECT_EQ(anIt.Value().ShapeType(), TopAbs_VERTEX);
++aCount;
}
EXPECT_EQ(aCount, 5) << "Should iterate over 5 vertices";
}
//=================================================================================================
// Test iterator on wire with edges
//=================================================================================================
TEST(TopoDS_Iterator_Test, WireWithEdges)
{
TopoDS_Builder aBuilder;
TopoDS_Wire aWire;
aBuilder.MakeWire(aWire);
// Create a rectangular wire (4 edges)
TopoDS_Edge aE1 = BRepBuilderAPI_MakeEdge(gp_Pnt(0, 0, 0), gp_Pnt(1, 0, 0));
TopoDS_Edge aE2 = BRepBuilderAPI_MakeEdge(gp_Pnt(1, 0, 0), gp_Pnt(1, 1, 0));
TopoDS_Edge aE3 = BRepBuilderAPI_MakeEdge(gp_Pnt(1, 1, 0), gp_Pnt(0, 1, 0));
TopoDS_Edge aE4 = BRepBuilderAPI_MakeEdge(gp_Pnt(0, 1, 0), gp_Pnt(0, 0, 0));
aBuilder.Add(aWire, aE1);
aBuilder.Add(aWire, aE2);
aBuilder.Add(aWire, aE3);
aBuilder.Add(aWire, aE4);
// Iterate and verify
int aCount = 0;
for (TopoDS_Iterator anIt(aWire); anIt.More(); anIt.Next())
{
EXPECT_EQ(anIt.Value().ShapeType(), TopAbs_EDGE);
++aCount;
}
EXPECT_EQ(aCount, 4) << "Wire should have 4 edges";
}
//=================================================================================================
// Test iterator on edge with vertices
//=================================================================================================
TEST(TopoDS_Iterator_Test, EdgeWithVertices)
{
TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge(gp_Pnt(0, 0, 0), gp_Pnt(1, 1, 1));
int aCount = 0;
for (TopoDS_Iterator anIt(anEdge); anIt.More(); anIt.Next())
{
EXPECT_EQ(anIt.Value().ShapeType(), TopAbs_VERTEX);
++aCount;
}
EXPECT_EQ(aCount, 2) << "Edge should have 2 vertices";
}
//=================================================================================================
// Test iterator on vertex (no children)
//=================================================================================================
TEST(TopoDS_Iterator_Test, VertexNoChildren)
{
TopoDS_Vertex aVertex = BRepBuilderAPI_MakeVertex(gp_Pnt(0, 0, 0));
TopoDS_Iterator anIt(aVertex);
EXPECT_FALSE(anIt.More()) << "Vertex should have no children";
}
//=================================================================================================
// Test iterator cumulative orientation
//=================================================================================================
TEST(TopoDS_Iterator_Test, CumulativeOrientation)
{
TopoDS_Builder aBuilder;
TopoDS_Compound aCompound;
aBuilder.MakeCompound(aCompound);
TopoDS_Vertex aV = BRepBuilderAPI_MakeVertex(gp_Pnt(0, 0, 0));
aBuilder.Add(aCompound, aV);
// Reverse the compound
aCompound.Reverse();
// With cumOri=true (default), child orientation should be composed
TopoDS_Iterator anIt1(aCompound, true, true);
EXPECT_TRUE(anIt1.More());
TopAbs_Orientation anOri1 = anIt1.Value().Orientation();
// With cumOri=false, child orientation should be original
TopoDS_Iterator anIt2(aCompound, false, true);
EXPECT_TRUE(anIt2.More());
TopAbs_Orientation anOri2 = anIt2.Value().Orientation();
// Orientations should differ when compound is reversed
EXPECT_NE(anOri1, anOri2) << "Cumulative orientation should affect result";
}
//=================================================================================================
// Test iterator re-initialization
//=================================================================================================
TEST(TopoDS_Iterator_Test, ReInitialization)
{
TopoDS_Builder aBuilder;
TopoDS_Compound aCompound1, aCompound2;
aBuilder.MakeCompound(aCompound1);
aBuilder.MakeCompound(aCompound2);
// Add different number of vertices
for (int i = 0; i < 3; ++i)
{
aBuilder.Add(aCompound1, BRepBuilderAPI_MakeVertex(gp_Pnt(i, 0, 0)));
}
for (int i = 0; i < 5; ++i)
{
aBuilder.Add(aCompound2, BRepBuilderAPI_MakeVertex(gp_Pnt(i, 1, 0)));
}
TopoDS_Iterator anIt(aCompound1);
// Count first compound
int aCount1 = 0;
for (; anIt.More(); anIt.Next())
++aCount1;
EXPECT_EQ(aCount1, 3);
// Re-initialize with second compound
anIt.Initialize(aCompound2);
// Count second compound
int aCount2 = 0;
for (; anIt.More(); anIt.Next())
++aCount2;
EXPECT_EQ(aCount2, 5);
}
//=================================================================================================
// Test iterator on box solid (shell -> faces)
//=================================================================================================
TEST(TopoDS_Iterator_Test, BoxSolidIteration)
{
// Create a box
TopoDS_Shape aBox = BRepPrimAPI_MakeBox(1.0, 2.0, 3.0).Shape();
// Iterate over solid's children (should be 1 shell)
int aShellCount = 0;
for (TopoDS_Iterator anIt(aBox); anIt.More(); anIt.Next())
{
EXPECT_EQ(anIt.Value().ShapeType(), TopAbs_SHELL);
++aShellCount;
// Iterate over shell's children (should be 6 faces)
int aFaceCount = 0;
for (TopoDS_Iterator anIt2(anIt.Value()); anIt2.More(); anIt2.Next())
{
EXPECT_EQ(anIt2.Value().ShapeType(), TopAbs_FACE);
++aFaceCount;
}
EXPECT_EQ(aFaceCount, 6) << "Box shell should have 6 faces";
}
EXPECT_EQ(aShellCount, 1) << "Box solid should have 1 shell";
}
//=================================================================================================
// Test iterator with many children (performance/stress test)
//=================================================================================================
TEST(TopoDS_Iterator_Test, ManyChildren)
{
TopoDS_Builder aBuilder;
TopoDS_Compound aCompound;
aBuilder.MakeCompound(aCompound);
const int aNbVertices = 1000;
// Add many vertices
for (int i = 0; i < aNbVertices; ++i)
{
aBuilder.Add(aCompound, BRepBuilderAPI_MakeVertex(gp_Pnt(i, 0, 0)));
}
// Iterate and count
int aCount = 0;
for (TopoDS_Iterator anIt(aCompound); anIt.More(); anIt.Next())
{
++aCount;
}
EXPECT_EQ(aCount, aNbVertices) << "Should iterate over all vertices";
}
//=================================================================================================
// Test default constructor followed by Initialize
//=================================================================================================
TEST(TopoDS_Iterator_Test, DefaultConstructorThenInitialize)
{
TopoDS_Builder aBuilder;
TopoDS_Compound aCompound;
aBuilder.MakeCompound(aCompound);
aBuilder.Add(aCompound, BRepBuilderAPI_MakeVertex(gp_Pnt(0, 0, 0)));
// Default construct, then initialize
TopoDS_Iterator anIt;
EXPECT_FALSE(anIt.More()) << "Default constructed iterator should have More()=false";
anIt.Initialize(aCompound);
EXPECT_TRUE(anIt.More()) << "After Initialize, More() should be true";
EXPECT_EQ(anIt.Value().ShapeType(), TopAbs_VERTEX);
}
//=================================================================================================
// Test Value() throws when not More() (only in debug builds with exceptions enabled)
//=================================================================================================
#ifndef No_Exception
TEST(TopoDS_Iterator_Test, ValueThrowsWhenNotMore)
{
TopoDS_Builder aBuilder;
TopoDS_Compound aCompound;
aBuilder.MakeCompound(aCompound);
TopoDS_Iterator anIt(aCompound);
EXPECT_FALSE(anIt.More());
// Value() should throw Standard_NoSuchObject when !More()
EXPECT_THROW(anIt.Value(), Standard_NoSuchObject);
}
#endif
//=================================================================================================
// Test iterator with cumulative location
//=================================================================================================
TEST(TopoDS_Iterator_Test, CumulativeLocation)
{
TopoDS_Builder aBuilder;
TopoDS_Compound aCompound;
aBuilder.MakeCompound(aCompound);
TopoDS_Vertex aV = BRepBuilderAPI_MakeVertex(gp_Pnt(0, 0, 0));
aBuilder.Add(aCompound, aV);
// Apply a translation to the compound
gp_Trsf aTrsf;
aTrsf.SetTranslation(gp_Vec(10, 20, 30));
TopLoc_Location aLoc(aTrsf);
aCompound.Location(aLoc);
// With cumLoc=true (default), child should have composed location
TopoDS_Iterator anIt1(aCompound, true, true);
EXPECT_TRUE(anIt1.More());
TopLoc_Location aChildLoc1 = anIt1.Value().Location();
// With cumLoc=false, child should have original location
TopoDS_Iterator anIt2(aCompound, true, false);
EXPECT_TRUE(anIt2.More());
TopLoc_Location aChildLoc2 = anIt2.Value().Location();
// Locations should differ
EXPECT_NE(aChildLoc1.IsIdentity(), aChildLoc2.IsIdentity())
<< "Cumulative location should affect child location";
}
//=================================================================================================
// Test iterator on nested compounds
//=================================================================================================
TEST(TopoDS_Iterator_Test, NestedCompounds)
{
TopoDS_Builder aBuilder;
TopoDS_Compound aOuter, aInner1, aInner2;
aBuilder.MakeCompound(aOuter);
aBuilder.MakeCompound(aInner1);
aBuilder.MakeCompound(aInner2);
// Add vertices to inner compounds
aBuilder.Add(aInner1, BRepBuilderAPI_MakeVertex(gp_Pnt(0, 0, 0)));
aBuilder.Add(aInner1, BRepBuilderAPI_MakeVertex(gp_Pnt(1, 0, 0)));
aBuilder.Add(aInner2, BRepBuilderAPI_MakeVertex(gp_Pnt(2, 0, 0)));
// Add inner compounds to outer
aBuilder.Add(aOuter, aInner1);
aBuilder.Add(aOuter, aInner2);
// Outer should have 2 children (both compounds)
int aOuterCount = 0;
for (TopoDS_Iterator anIt(aOuter); anIt.More(); anIt.Next())
{
EXPECT_EQ(anIt.Value().ShapeType(), TopAbs_COMPOUND);
++aOuterCount;
}
EXPECT_EQ(aOuterCount, 2);
// First inner should have 2 children
TopoDS_Iterator anIt(aOuter);
int aInner1Count = 0;
for (TopoDS_Iterator anIt2(anIt.Value()); anIt2.More(); anIt2.Next())
{
++aInner1Count;
}
EXPECT_EQ(aInner1Count, 2);
}
//=================================================================================================
// Test iterator on face with wires (from box)
//=================================================================================================
TEST(TopoDS_Iterator_Test, FaceWithWires)
{
TopoDS_Shape aBox = BRepPrimAPI_MakeBox(1.0, 1.0, 1.0).Shape();
// Get first face
TopExp_Explorer anExp(aBox, TopAbs_FACE);
ASSERT_TRUE(anExp.More());
const TopoDS_Face& aFace = TopoDS::Face(anExp.Current());
// Iterate over face's children (should be wires)
int aWireCount = 0;
for (TopoDS_Iterator anIt(aFace); anIt.More(); anIt.Next())
{
EXPECT_EQ(anIt.Value().ShapeType(), TopAbs_WIRE);
++aWireCount;
}
EXPECT_GE(aWireCount, 1) << "Face should have at least 1 wire";
}
//=================================================================================================
// Test iterator preserves shape identity
//=================================================================================================
TEST(TopoDS_Iterator_Test, ShapeIdentity)
{
TopoDS_Builder aBuilder;
TopoDS_Compound aCompound;
aBuilder.MakeCompound(aCompound);
TopoDS_Vertex aV1 = BRepBuilderAPI_MakeVertex(gp_Pnt(1, 0, 0));
TopoDS_Vertex aV2 = BRepBuilderAPI_MakeVertex(gp_Pnt(2, 0, 0));
aBuilder.Add(aCompound, aV1);
aBuilder.Add(aCompound, aV2);
// Iterate and check that TShape pointers match
TopoDS_Iterator anIt(aCompound);
EXPECT_TRUE(anIt.Value().TShape() == aV1.TShape() || anIt.Value().TShape() == aV2.TShape());
anIt.Next();
EXPECT_TRUE(anIt.Value().TShape() == aV1.TShape() || anIt.Value().TShape() == aV2.TShape());
}
//=================================================================================================
// Test iterator on shell with faces
//=================================================================================================
TEST(TopoDS_Iterator_Test, ShellWithFaces)
{
TopoDS_Shape aBox = BRepPrimAPI_MakeBox(1.0, 1.0, 1.0).Shape();
// Get shell from box
TopExp_Explorer anExp(aBox, TopAbs_SHELL);
ASSERT_TRUE(anExp.More());
const TopoDS_Shell& aShell = TopoDS::Shell(anExp.Current());
// Iterate over shell's faces
int aFaceCount = 0;
for (TopoDS_Iterator anIt(aShell); anIt.More(); anIt.Next())
{
EXPECT_EQ(anIt.Value().ShapeType(), TopAbs_FACE);
++aFaceCount;
}
EXPECT_EQ(aFaceCount, 6) << "Box shell should have 6 faces";
}

View File

@@ -0,0 +1,313 @@
// Copyright (c) 2026 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 <gtest/gtest.h>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeVertex.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Builder.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopoDS_Shell.hxx>
#include <TopoDS_Solid.hxx>
#include <TopoDS_TShape.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Wire.hxx>
#include <TopExp_Explorer.hxx>
#include <gp_Pnt.hxx>
//==================================================================================================
// Test TShape ShapeType() returns correct type for each shape kind
//==================================================================================================
TEST(TopoDS_TShape_Test, ShapeType_AllTypes)
{
TopoDS_Builder aBuilder;
// Create various shapes and verify ShapeType
TopoDS_Vertex aVertex = BRepBuilderAPI_MakeVertex(gp_Pnt(0, 0, 0));
EXPECT_EQ(aVertex.TShape()->ShapeType(), TopAbs_VERTEX);
TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge(gp_Pnt(0, 0, 0), gp_Pnt(1, 0, 0));
EXPECT_EQ(anEdge.TShape()->ShapeType(), TopAbs_EDGE);
TopoDS_Wire aWire;
aBuilder.MakeWire(aWire);
EXPECT_EQ(aWire.TShape()->ShapeType(), TopAbs_WIRE);
TopoDS_Shell aShell;
aBuilder.MakeShell(aShell);
EXPECT_EQ(aShell.TShape()->ShapeType(), TopAbs_SHELL);
TopoDS_Solid aSolid;
aBuilder.MakeSolid(aSolid);
EXPECT_EQ(aSolid.TShape()->ShapeType(), TopAbs_SOLID);
TopoDS_CompSolid aCompSolid;
aBuilder.MakeCompSolid(aCompSolid);
EXPECT_EQ(aCompSolid.TShape()->ShapeType(), TopAbs_COMPSOLID);
TopoDS_Compound aCompound;
aBuilder.MakeCompound(aCompound);
EXPECT_EQ(aCompound.TShape()->ShapeType(), TopAbs_COMPOUND);
}
//==================================================================================================
// Test TShape flag setters and getters
//==================================================================================================
TEST(TopoDS_TShape_Test, FlagSettersGetters)
{
TopoDS_Builder aBuilder;
TopoDS_Compound aCompound;
aBuilder.MakeCompound(aCompound);
TopoDS_TShape* aTShape = aCompound.TShape().get();
// Test Free flag
EXPECT_TRUE(aTShape->Free());
aTShape->Free(false);
EXPECT_FALSE(aTShape->Free());
aTShape->Free(true);
EXPECT_TRUE(aTShape->Free());
// Test Modified flag
EXPECT_TRUE(aTShape->Modified());
aTShape->Modified(false);
EXPECT_FALSE(aTShape->Modified());
// Test Checked flag
EXPECT_FALSE(aTShape->Checked());
aTShape->Checked(true);
EXPECT_TRUE(aTShape->Checked());
// Test that setting Modified(true) clears Checked
aTShape->Modified(true);
EXPECT_FALSE(aTShape->Checked()) << "Modified(true) should clear Checked flag";
// Test Orientable flag
EXPECT_FALSE(aTShape->Orientable()) << "Compound should not be orientable";
// Test Closed flag
EXPECT_FALSE(aTShape->Closed());
aTShape->Closed(true);
EXPECT_TRUE(aTShape->Closed());
// Test Infinite flag
EXPECT_FALSE(aTShape->Infinite());
aTShape->Infinite(true);
EXPECT_TRUE(aTShape->Infinite());
// Test Convex flag
EXPECT_FALSE(aTShape->Convex());
aTShape->Convex(true);
EXPECT_TRUE(aTShape->Convex());
// Test Locked flag
EXPECT_FALSE(aTShape->Locked());
aTShape->Locked(true);
EXPECT_TRUE(aTShape->Locked());
}
//==================================================================================================
// Test TShape NbChildren() for various shapes
//==================================================================================================
TEST(TopoDS_TShape_Test, NbChildren)
{
TopoDS_Builder aBuilder;
// Vertex has 0 children
TopoDS_Vertex aVertex = BRepBuilderAPI_MakeVertex(gp_Pnt(0, 0, 0));
EXPECT_EQ(aVertex.TShape()->NbChildren(), 0);
// Edge has 2 children (vertices)
TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge(gp_Pnt(0, 0, 0), gp_Pnt(1, 0, 0));
EXPECT_EQ(anEdge.TShape()->NbChildren(), 2);
// Empty wire has 0 children
TopoDS_Wire aWire;
aBuilder.MakeWire(aWire);
EXPECT_EQ(aWire.TShape()->NbChildren(), 0);
// Wire with edges
aBuilder.Add(aWire, anEdge);
EXPECT_EQ(aWire.TShape()->NbChildren(), 1);
// Compound with multiple children
TopoDS_Compound aCompound;
aBuilder.MakeCompound(aCompound);
for (int i = 0; i < 10; ++i)
{
aBuilder.Add(aCompound, BRepBuilderAPI_MakeVertex(gp_Pnt(i, 0, 0)));
}
EXPECT_EQ(aCompound.TShape()->NbChildren(), 10);
}
//==================================================================================================
// Test TShape EmptyCopy creates same type with no children
//==================================================================================================
TEST(TopoDS_TShape_Test, EmptyCopy)
{
TopoDS_Builder aBuilder;
// Create compound with children
TopoDS_Compound aCompound;
aBuilder.MakeCompound(aCompound);
aBuilder.Add(aCompound, BRepBuilderAPI_MakeVertex(gp_Pnt(0, 0, 0)));
aBuilder.Add(aCompound, BRepBuilderAPI_MakeVertex(gp_Pnt(1, 0, 0)));
EXPECT_EQ(aCompound.TShape()->NbChildren(), 2);
// EmptyCopy should create same type with no children
occ::handle<TopoDS_TShape> aCopy = aCompound.TShape()->EmptyCopy();
EXPECT_EQ(aCopy->ShapeType(), TopAbs_COMPOUND);
EXPECT_EQ(aCopy->NbChildren(), 0) << "EmptyCopy should have no children";
}
//==================================================================================================
// Test TShape EmptyCopy for all shape types
//==================================================================================================
TEST(TopoDS_TShape_Test, EmptyCopy_AllTypes)
{
TopoDS_Builder aBuilder;
// Test Edge EmptyCopy
{
TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge(gp_Pnt(0, 0, 0), gp_Pnt(1, 0, 0));
occ::handle<TopoDS_TShape> aCopy = anEdge.TShape()->EmptyCopy();
EXPECT_EQ(aCopy->ShapeType(), TopAbs_EDGE);
EXPECT_EQ(aCopy->NbChildren(), 0);
}
// Test Wire EmptyCopy
{
TopoDS_Wire aWire;
aBuilder.MakeWire(aWire);
occ::handle<TopoDS_TShape> aCopy = aWire.TShape()->EmptyCopy();
EXPECT_EQ(aCopy->ShapeType(), TopAbs_WIRE);
}
// Test Shell EmptyCopy
{
TopoDS_Shell aShell;
aBuilder.MakeShell(aShell);
occ::handle<TopoDS_TShape> aCopy = aShell.TShape()->EmptyCopy();
EXPECT_EQ(aCopy->ShapeType(), TopAbs_SHELL);
}
// Test Solid EmptyCopy
{
TopoDS_Solid aSolid;
aBuilder.MakeSolid(aSolid);
occ::handle<TopoDS_TShape> aCopy = aSolid.TShape()->EmptyCopy();
EXPECT_EQ(aCopy->ShapeType(), TopAbs_SOLID);
}
// Test CompSolid EmptyCopy
{
TopoDS_CompSolid aCompSolid;
aBuilder.MakeCompSolid(aCompSolid);
occ::handle<TopoDS_TShape> aCopy = aCompSolid.TShape()->EmptyCopy();
EXPECT_EQ(aCopy->ShapeType(), TopAbs_COMPSOLID);
}
}
//==================================================================================================
// Test TShape Orientable flag for different shape types
//==================================================================================================
TEST(TopoDS_TShape_Test, Orientable_DifferentTypes)
{
TopoDS_Builder aBuilder;
// Edge should be orientable
TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge(gp_Pnt(0, 0, 0), gp_Pnt(1, 0, 0));
EXPECT_TRUE(anEdge.TShape()->Orientable()) << "Edge should be orientable";
// Compound should not be orientable
TopoDS_Compound aCompound;
aBuilder.MakeCompound(aCompound);
EXPECT_FALSE(aCompound.TShape()->Orientable()) << "Compound should not be orientable";
// Wire should be orientable
TopoDS_Wire aWire;
aBuilder.MakeWire(aWire);
EXPECT_TRUE(aWire.TShape()->Orientable()) << "Wire should be orientable";
}
//==================================================================================================
// Test TShape flags are independent
//==================================================================================================
TEST(TopoDS_TShape_Test, FlagsIndependent)
{
TopoDS_Builder aBuilder;
TopoDS_Compound aCompound;
aBuilder.MakeCompound(aCompound);
TopoDS_TShape* aTShape = aCompound.TShape().get();
// Set all flags
aTShape->Closed(true);
aTShape->Infinite(true);
aTShape->Convex(true);
aTShape->Locked(true);
// Verify all are set
EXPECT_TRUE(aTShape->Closed());
EXPECT_TRUE(aTShape->Infinite());
EXPECT_TRUE(aTShape->Convex());
EXPECT_TRUE(aTShape->Locked());
// Clear one flag, others should remain
aTShape->Closed(false);
EXPECT_FALSE(aTShape->Closed());
EXPECT_TRUE(aTShape->Infinite()) << "Clearing Closed should not affect Infinite";
EXPECT_TRUE(aTShape->Convex()) << "Clearing Closed should not affect Convex";
EXPECT_TRUE(aTShape->Locked()) << "Clearing Closed should not affect Locked";
}
//==================================================================================================
// Test NbChildren consistency with iterator
//==================================================================================================
TEST(TopoDS_TShape_Test, NbChildren_ConsistencyWithIterator)
{
TopoDS_Builder aBuilder;
// Create wire with edge
TopoDS_Wire aWire;
aBuilder.MakeWire(aWire);
TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge(gp_Pnt(0, 0, 0), gp_Pnt(1, 0, 0));
aBuilder.Add(aWire, anEdge);
// Get NbChildren via TShape
int aNbViaTShape = aWire.TShape()->NbChildren();
// Count via iterator
int aNbViaIterator = 0;
for (TopoDS_Iterator anIt(aWire); anIt.More(); anIt.Next())
{
++aNbViaIterator;
}
EXPECT_EQ(aNbViaTShape, aNbViaIterator) << "NbChildren should match iterator count";
EXPECT_EQ(aNbViaTShape, 1);
}

View File

@@ -22,12 +22,9 @@
#include <TopoDS_TShape.hxx>
#include <TopoDS_TWire.hxx>
#include <TopoDS_UnCompatibleShapes.hxx>
class TopoDS_Shape;
//=======================================================================
// function : MakeShape
// purpose : Make a Shape from a TShape
//=======================================================================
//==================================================================================================
void TopoDS_Builder::MakeShape(TopoDS_Shape& S, const occ::handle<TopoDS_TShape>& T) const
{
S.TShape(T);
@@ -35,10 +32,7 @@ void TopoDS_Builder::MakeShape(TopoDS_Shape& S, const occ::handle<TopoDS_TShape>
S.Orientation(TopAbs_FORWARD);
}
//=======================================================================
// function : Add
// purpose : insert aComponent in aShape
//=======================================================================
//==================================================================================================
void TopoDS_Builder::Add(TopoDS_Shape& aShape, const TopoDS_Shape& aComponent) const
{
@@ -71,27 +65,27 @@ void TopoDS_Builder::Add(TopoDS_Shape& aShape, const TopoDS_Shape& aComponent) c
| (1 << ((unsigned int)TopAbs_FACE)) | (1 << ((unsigned int)TopAbs_EDGE)),
// SHAPE to:
0};
//
const unsigned int iC = (unsigned int)aComponent.ShapeType();
const unsigned int iS = (unsigned int)aShape.ShapeType();
//
if ((aTb[iC] & (1 << iS)) != 0)
{
NCollection_List<TopoDS_Shape>& L = aShape.TShape()->myShapes;
L.Append(aComponent);
TopoDS_Shape& S = L.Last();
//
TopoDS_Shape aChild = aComponent;
// compute the relative Orientation
if (aShape.Orientation() == TopAbs_REVERSED)
S.Reverse();
//
aChild.Reverse();
// and the Relative Location
const TopLoc_Location& aLoc = aShape.Location();
if (!aLoc.IsIdentity())
S.Move(aLoc.Inverted(), false);
//
// Set the TShape as modified.
aShape.TShape()->Modified(true);
aChild.Move(aLoc.Inverted(), false);
// Add to the subshapes list
TopoDS_TShape* aTShape = aShape.TShape().get();
aTShape->myShapes.Append(aChild);
aTShape->Modified(true);
}
else
{
@@ -104,14 +98,11 @@ void TopoDS_Builder::Add(TopoDS_Shape& aShape, const TopoDS_Shape& aComponent) c
}
}
//=======================================================================
// function : Remove
// purpose : Remove a Shape from an other one
//=======================================================================
//==================================================================================================
void TopoDS_Builder::Remove(TopoDS_Shape& aShape, const TopoDS_Shape& aComponent) const
{
// check if aShape is not Frozen
// check if aShape is not Frozen
TopoDS_FrozenShape_Raise_if(!aShape.Free(), "TopoDS_Builder::Remove");
// compute the relative Orientation and Location of aComponent
@@ -120,16 +111,18 @@ void TopoDS_Builder::Remove(TopoDS_Shape& aShape, const TopoDS_Shape& aComponent
S.Reverse();
S.Location(S.Location().Predivided(aShape.Location()), false);
NCollection_List<TopoDS_Shape>& L = aShape.TShape()->myShapes;
NCollection_List<TopoDS_Shape>::Iterator It(L);
while (It.More())
TopoDS_TShape* aTShape = aShape.TShape().get();
NCollection_List<TopoDS_Shape>& aList = aTShape->myShapes;
NCollection_List<TopoDS_Shape>::Iterator anIter(aList);
while (anIter.More())
{
if (It.Value() == S)
if (anIter.Value() == S)
{
L.Remove(It);
aShape.TShape()->Modified(true);
break;
aList.Remove(anIter);
aTShape->Modified(true);
return;
}
It.Next();
anIter.Next();
}
}

View File

@@ -25,7 +25,7 @@
#include <TopoDS_CompSolid.hxx>
#include <TopoDS_Compound.hxx>
//=================================================================================================
//==================================================================================================
inline void TopoDS_Builder::MakeWire(TopoDS_Wire& W) const
{
@@ -33,7 +33,7 @@ inline void TopoDS_Builder::MakeWire(TopoDS_Wire& W) const
MakeShape(W, TW);
}
//=================================================================================================
//==================================================================================================
inline void TopoDS_Builder::MakeShell(TopoDS_Shell& S) const
{
@@ -41,7 +41,7 @@ inline void TopoDS_Builder::MakeShell(TopoDS_Shell& S) const
MakeShape(S, TS);
}
//=================================================================================================
//==================================================================================================
inline void TopoDS_Builder::MakeSolid(TopoDS_Solid& S) const
{
@@ -49,10 +49,7 @@ inline void TopoDS_Builder::MakeSolid(TopoDS_Solid& S) const
MakeShape(S, TS);
}
//=======================================================================
// function : MakeCompSolid
// purpose : Make an empty CompSolid
//=======================================================================
//==================================================================================================
inline void TopoDS_Builder::MakeCompSolid(TopoDS_CompSolid& C) const
{
@@ -60,10 +57,7 @@ inline void TopoDS_Builder::MakeCompSolid(TopoDS_CompSolid& C) const
MakeShape(C, TC);
}
//=======================================================================
// function : MakeCompound
// purpose : Make an empty Compound
//=======================================================================
//==================================================================================================
inline void TopoDS_Builder::MakeCompound(TopoDS_Compound& C) const
{

View File

@@ -17,8 +17,9 @@
#define No_Standard_NoSuchObject
#include <TopoDS_Iterator.hxx>
#include <TopoDS_TShape.hxx>
//=================================================================================================
//==================================================================================================
void TopoDS_Iterator::Initialize(const TopoDS_Shape& S, const bool cumOri, const bool cumLoc)
{
@@ -26,35 +27,44 @@ void TopoDS_Iterator::Initialize(const TopoDS_Shape& S, const bool cumOri, const
myLocation = S.Location();
else
myLocation.Identity();
if (cumOri)
myOrientation = S.Orientation();
else
myOrientation = TopAbs_FORWARD;
if (S.IsNull())
myShapes = NCollection_List<TopoDS_Shape>::Iterator();
{
myIterator = NCollection_List<TopoDS_Shape>::Iterator();
}
else
myShapes.Initialize(S.TShape()->myShapes);
{
myIterator.Init(S.TShape()->myShapes);
}
if (More())
{
myShape = myShapes.Value();
myShape.Orientation(TopAbs::Compose(myOrientation, myShape.Orientation()));
if (!myLocation.IsIdentity())
myShape.Move(myLocation, false);
updateCurrentShape();
}
}
//=================================================================================================
//==================================================================================================
void TopoDS_Iterator::Next()
{
myShapes.Next();
myIterator.Next();
if (More())
{
myShape = myShapes.Value();
myShape.Orientation(TopAbs::Compose(myOrientation, myShape.Orientation()));
if (!myLocation.IsIdentity())
myShape.Move(myLocation, false);
updateCurrentShape();
}
}
//==================================================================================================
void TopoDS_Iterator::updateCurrentShape()
{
myShape = myIterator.Value();
myShape.Orientation(TopAbs::Compose(myOrientation, myShape.Orientation()));
if (!myLocation.IsIdentity())
myShape.Move(myLocation, false);
}

View File

@@ -18,11 +18,10 @@
#define _TopoDS_Iterator_HeaderFile
#include <Standard_NoSuchObject.hxx>
#include <TopoDS_Shape.hxx>
#include <NCollection_List.hxx>
#include <TopoDS_Shape.hxx>
#include <TopAbs_Orientation.hxx>
#include <TopLoc_Location.hxx>
class TopoDS_Shape;
//! Iterates on the underlying shape underlying a given
//! TopoDS_Shape object, providing access to its
@@ -48,6 +47,7 @@ public:
//! sub-shapes by the location of S, i.e. it applies to
//! each sub-shape the transformation that is associated with S.
TopoDS_Iterator(const TopoDS_Shape& S, const bool cumOri = true, const bool cumLoc = true)
: myOrientation(TopAbs_FORWARD)
{
Initialize(S, cumOri, cumLoc);
}
@@ -65,7 +65,7 @@ public:
//! Returns true if there is another sub-shape in the
//! shape which this iterator is scanning.
bool More() const { return myShapes.More(); }
bool More() const { return myIterator.More(); }
//! Moves on to the next sub-shape in the shape which
//! this iterator is scanning.
@@ -84,10 +84,14 @@ public:
}
private:
TopoDS_Shape myShape;
NCollection_List<TopoDS_Shape>::Iterator myShapes;
TopAbs_Orientation myOrientation;
TopLoc_Location myLocation;
//! Updates myShape from the current iterator position.
void updateCurrentShape();
private:
TopoDS_Shape myShape; //!< Current composed sub-shape
NCollection_List<TopoDS_Shape>::Iterator myIterator; //!< Iterator over child shapes list
TopAbs_Orientation myOrientation; //!< Cumulative orientation
TopLoc_Location myLocation; //!< Cumulative location
};
#endif // _TopoDS_Iterator_HeaderFile

View File

@@ -22,13 +22,6 @@ IMPLEMENT_STANDARD_RTTIEXT(TopoDS_TCompSolid, TopoDS_TShape)
//=================================================================================================
TopAbs_ShapeEnum TopoDS_TCompSolid::ShapeType() const
{
return TopAbs_COMPSOLID;
}
//=================================================================================================
occ::handle<TopoDS_TShape> TopoDS_TCompSolid::EmptyCopy() const
{
return occ::handle<TopoDS_TCompSolid>(new TopoDS_TCompSolid());

View File

@@ -19,7 +19,6 @@
#include <Standard.hxx>
#include <Standard_Type.hxx>
#include <TopAbs_ShapeEnum.hxx>
#include <TopoDS_TShape.hxx>
//! A set of solids connected by their faces.
@@ -28,11 +27,9 @@ class TopoDS_TCompSolid : public TopoDS_TShape
public:
//! Creates an empty TCompSolid.
TopoDS_TCompSolid()
= default;
//! returns COMPSOLID
Standard_EXPORT TopAbs_ShapeEnum ShapeType() const override;
: TopoDS_TShape(TopAbs_COMPSOLID)
{
}
//! Returns an empty TCompSolid.
Standard_EXPORT occ::handle<TopoDS_TShape> EmptyCopy() const override;

View File

@@ -22,13 +22,6 @@ IMPLEMENT_STANDARD_RTTIEXT(TopoDS_TCompound, TopoDS_TShape)
//=================================================================================================
TopAbs_ShapeEnum TopoDS_TCompound::ShapeType() const
{
return TopAbs_COMPOUND;
}
//=================================================================================================
occ::handle<TopoDS_TShape> TopoDS_TCompound::EmptyCopy() const
{
return occ::handle<TopoDS_TCompound>(new TopoDS_TCompound());

View File

@@ -19,7 +19,6 @@
#include <Standard.hxx>
#include <Standard_Type.hxx>
#include <TopAbs_ShapeEnum.hxx>
#include <TopoDS_TShape.hxx>
//! A TCompound is an all-purpose set of Shapes.
@@ -27,10 +26,11 @@ class TopoDS_TCompound : public TopoDS_TShape
{
public:
//! Creates an empty TCompound.
TopoDS_TCompound() { Orientable(false); }
//! Returns COMPOUND.
Standard_EXPORT TopAbs_ShapeEnum ShapeType() const override;
TopoDS_TCompound()
: TopoDS_TShape(TopAbs_COMPOUND)
{
Orientable(false);
}
//! Returns an empty TCompound.
Standard_EXPORT occ::handle<TopoDS_TShape> EmptyCopy() const override;

View File

@@ -21,7 +21,7 @@ IMPLEMENT_STANDARD_RTTIEXT(TopoDS_TEdge, TopoDS_TShape)
//=================================================================================================
TopAbs_ShapeEnum TopoDS_TEdge::ShapeType() const
occ::handle<TopoDS_TShape> TopoDS_TEdge::EmptyCopy() const
{
return TopAbs_EDGE;
return occ::handle<TopoDS_TEdge>(new TopoDS_TEdge());
}

View File

@@ -18,8 +18,6 @@
#define _TopoDS_TEdge_HeaderFile
#include <Standard.hxx>
#include <TopAbs_ShapeEnum.hxx>
#include <TopoDS_TShape.hxx>
//! A topological part of a curve in 2D or 3D, the
@@ -27,14 +25,17 @@
class TopoDS_TEdge : public TopoDS_TShape
{
public:
//! Returns EDGE.
Standard_EXPORT TopAbs_ShapeEnum ShapeType() const override;
//! Returns an empty TEdge.
Standard_EXPORT occ::handle<TopoDS_TShape> EmptyCopy() const override;
DEFINE_STANDARD_RTTIEXT(TopoDS_TEdge, TopoDS_TShape)
protected:
//! Construct an edge.
TopoDS_TEdge() {}
TopoDS_TEdge()
: TopoDS_TShape(TopAbs_EDGE)
{
}
};
#endif // _TopoDS_TEdge_HeaderFile

View File

@@ -22,13 +22,6 @@ IMPLEMENT_STANDARD_RTTIEXT(TopoDS_TFace, TopoDS_TShape)
//=================================================================================================
TopAbs_ShapeEnum TopoDS_TFace::ShapeType() const
{
return TopAbs_FACE;
}
//=================================================================================================
occ::handle<TopoDS_TShape> TopoDS_TFace::EmptyCopy() const
{
return occ::handle<TopoDS_TFace>(new TopoDS_TFace());

View File

@@ -19,22 +19,18 @@
#include <Standard.hxx>
#include <Standard_Type.hxx>
#include <TopAbs_ShapeEnum.hxx>
#include <TopoDS_TShape.hxx>
//! A topological part of a surface or of the 2D
//! space. The boundary is a set of wires and
//! vertices.
//! space. The boundary is a set of wires and vertices.
class TopoDS_TFace : public TopoDS_TShape
{
public:
//! Creates an empty TFace.
TopoDS_TFace()
= default;
//! returns FACE.
Standard_EXPORT TopAbs_ShapeEnum ShapeType() const override;
: TopoDS_TShape(TopAbs_FACE)
{
}
//! Returns an empty TFace.
Standard_EXPORT occ::handle<TopoDS_TShape> EmptyCopy() const override;

View File

@@ -32,9 +32,7 @@ void TopoDS_TShape::DumpJson(Standard_OStream& theOStream, int) const
OCCT_DUMP_FIELD_VALUE_NUMERICAL(theOStream, ShapeType())
OCCT_DUMP_FIELD_VALUE_NUMERICAL(theOStream, NbChildren())
OCCT_DUMP_FIELD_VALUE_NUMERICAL(theOStream, myFlags)
OCCT_DUMP_FIELD_VALUE_NUMERICAL(theOStream, Free())
OCCT_DUMP_FIELD_VALUE_NUMERICAL(theOStream, myState)
OCCT_DUMP_FIELD_VALUE_NUMERICAL(theOStream, Free())
OCCT_DUMP_FIELD_VALUE_NUMERICAL(theOStream, Locked())

View File

@@ -17,9 +17,15 @@
#ifndef _TopoDS_TShape_HeaderFile
#define _TopoDS_TShape_HeaderFile
#include <Standard.hxx>
#include <Standard_Handle.hxx>
#include <Standard_Transient.hxx>
#include <Standard_Type.hxx>
#include <NCollection_List.hxx>
#include <TopAbs.hxx>
#include <TopAbs_ShapeEnum.hxx>
#include <NCollection_List.hxx>
class TopoDS_Shape;
// resolve name collisions with X11 headers
@@ -37,7 +43,7 @@ class TopoDS_Shape;
//! TShapes are defined by their optional domain
//! (geometry) and their components (other TShapes
//! with Locations and Orientations). The components
//! are stored in a List of Shapes.
//! are stored in a list in the base class.
//!
//! A TShape contains the following boolean flags:
//!
@@ -48,77 +54,97 @@ class TopoDS_Shape;
//! - Closed : Is closed (note that only Wires and Shells may be closed).
//! - Infinite : Is infinite.
//! - Convex : Is convex.
//! - Locked : Is locked against modifications.
//!
//! Users have no direct access to the classes derived
//! from TShape. They handle them with the classes
//! derived from Shape.
class TopoDS_TShape : public Standard_Transient
{
public:
//! Bit layout for compact state storage.
//! Bits 0-3 store the TopAbs_ShapeEnum value (0-8).
//! Bits 4-11 store boolean flags.
//! Bits 12-15 are reserved for future use.
enum BitLayout : uint16_t
{
Bits_ShapeType_Mask = 0x000F, //!< bits 0-3: shape type mask
Bits_ShapeType_Shift = 0, //!< shift for shape type
Bit_Free = 0x0010, //!< bit 4: free flag
Bit_Modified = 0x0020, //!< bit 5: modified flag
Bit_Checked = 0x0040, //!< bit 6: checked flag
Bit_Orientable = 0x0080, //!< bit 7: orientable flag
Bit_Closed = 0x0100, //!< bit 8: closed flag
Bit_Infinite = 0x0200, //!< bit 9: infinite flag
Bit_Convex = 0x0400, //!< bit 10: convex flag
Bit_Locked = 0x0800, //!< bit 11: locked flag
Bits_Reserved = 0xF000 //!< bits 12-15: reserved
};
public:
//! Returns the free flag.
bool Free() const { return ((myFlags & TopoDS_TShape_Flags_Free) != 0); }
bool Free() const { return (myState & Bit_Free) != 0; }
//! Sets the free flag.
void Free(bool theIsFree) { setFlag(TopoDS_TShape_Flags_Free, theIsFree); }
void Free(bool theIsFree) { setBit(Bit_Free, theIsFree); }
//! Returns the locked flag.
bool Locked() const { return ((myFlags & TopoDS_TShape_Flags_Locked) != 0); }
bool Locked() const { return (myState & Bit_Locked) != 0; }
//! Sets the locked flag.
void Locked(bool theIsLocked) { setFlag(TopoDS_TShape_Flags_Locked, theIsLocked); }
void Locked(bool theIsLocked) { setBit(Bit_Locked, theIsLocked); }
//! Returns the modification flag.
bool Modified() const { return ((myFlags & TopoDS_TShape_Flags_Modified) != 0); }
bool Modified() const { return (myState & Bit_Modified) != 0; }
//! Sets the modification flag.
void Modified(bool theIsModified)
{
setFlag(TopoDS_TShape_Flags_Modified, theIsModified);
setBit(Bit_Modified, theIsModified);
if (theIsModified)
{
// clang-format off
setFlag (TopoDS_TShape_Flags_Checked, false); // when a TShape is modified it is also unchecked
// clang-format on
// when a TShape is modified it is also unchecked
setBit(Bit_Checked, false);
}
}
//! Returns the checked flag.
bool Checked() const { return ((myFlags & TopoDS_TShape_Flags_Checked) != 0); }
bool Checked() const { return (myState & Bit_Checked) != 0; }
//! Sets the checked flag.
void Checked(bool theIsChecked) { setFlag(TopoDS_TShape_Flags_Checked, theIsChecked); }
void Checked(bool theIsChecked) { setBit(Bit_Checked, theIsChecked); }
//! Returns the orientability flag.
bool Orientable() const { return ((myFlags & TopoDS_TShape_Flags_Orientable) != 0); }
bool Orientable() const { return (myState & Bit_Orientable) != 0; }
//! Sets the orientability flag.
void Orientable(bool theIsOrientable)
{
setFlag(TopoDS_TShape_Flags_Orientable, theIsOrientable);
}
void Orientable(bool theIsOrientable) { setBit(Bit_Orientable, theIsOrientable); }
//! Returns the closedness flag.
bool Closed() const { return ((myFlags & TopoDS_TShape_Flags_Closed) != 0); }
bool Closed() const { return (myState & Bit_Closed) != 0; }
//! Sets the closedness flag.
void Closed(bool theIsClosed) { setFlag(TopoDS_TShape_Flags_Closed, theIsClosed); }
void Closed(bool theIsClosed) { setBit(Bit_Closed, theIsClosed); }
//! Returns the infinity flag.
bool Infinite() const { return ((myFlags & TopoDS_TShape_Flags_Infinite) != 0); }
bool Infinite() const { return (myState & Bit_Infinite) != 0; }
//! Sets the infinity flag.
void Infinite(bool theIsInfinite) { setFlag(TopoDS_TShape_Flags_Infinite, theIsInfinite); }
void Infinite(bool theIsInfinite) { setBit(Bit_Infinite, theIsInfinite); }
//! Returns the convexness flag.
bool Convex() const { return ((myFlags & TopoDS_TShape_Flags_Convex) != 0); }
bool Convex() const { return (myState & Bit_Convex) != 0; }
//! Sets the convexness flag.
void Convex(bool theIsConvex) { setFlag(TopoDS_TShape_Flags_Convex, theIsConvex); }
void Convex(bool theIsConvex) { setBit(Bit_Convex, theIsConvex); }
//! Returns the type as a term of the ShapeEnum enum :
//! VERTEX, EDGE, WIRE, FACE, ....
Standard_EXPORT virtual TopAbs_ShapeEnum ShapeType() const = 0;
//! Returns the type as a term of the ShapeEnum enum:
//! VERTEX, EDGE, WIRE, FACE, SHELL, SOLID, COMPSOLID, COMPOUND.
//! The type is embedded in the lower 4 bits of the state.
TopAbs_ShapeEnum ShapeType() const
{
return static_cast<TopAbs_ShapeEnum>(myState & Bits_ShapeType_Mask);
}
//! Returns a copy of the TShape with no sub-shapes.
Standard_EXPORT virtual occ::handle<TopoDS_TShape> EmptyCopy() const = 0;
@@ -136,46 +162,28 @@ public:
DEFINE_STANDARD_RTTIEXT(TopoDS_TShape, Standard_Transient)
protected:
//! Constructs an empty TShape.
//! Free : True
//! Modified : True
//! Checked : False
//! Orientable : True
//! Closed : False
//! Infinite : False
//! Convex : False
TopoDS_TShape()
: myFlags(TopoDS_TShape_Flags_Free | TopoDS_TShape_Flags_Modified
| TopoDS_TShape_Flags_Orientable)
//! Constructs a TShape with the given shape type.
//! Default flags: Free = true, Modified = true, Orientable = true.
//! @param theType the shape type to embed in the state
TopoDS_TShape(TopAbs_ShapeEnum theType)
: myState(static_cast<uint16_t>(theType) | Bit_Free | Bit_Modified | Bit_Orientable)
{
}
private:
// Defined mask values
enum TopoDS_TShape_Flags
{
TopoDS_TShape_Flags_Free = 0x001,
TopoDS_TShape_Flags_Modified = 0x002,
TopoDS_TShape_Flags_Checked = 0x004,
TopoDS_TShape_Flags_Orientable = 0x008,
TopoDS_TShape_Flags_Closed = 0x010,
TopoDS_TShape_Flags_Infinite = 0x020,
TopoDS_TShape_Flags_Convex = 0x040,
TopoDS_TShape_Flags_Locked = 0x080
};
//! Set bit flag.
void setFlag(TopoDS_TShape_Flags theFlag, bool theIsOn)
//! Set a bit flag.
//! @param theBit the bit to set
//! @param theIsOn true to set, false to clear
void setBit(uint16_t theBit, bool theIsOn)
{
if (theIsOn)
myFlags |= (int)theFlag;
myState |= theBit;
else
myFlags &= ~(int)theFlag;
myState &= ~theBit;
}
private:
NCollection_List<TopoDS_Shape> myShapes;
int myFlags;
NCollection_List<TopoDS_Shape> myShapes; //!< Child shapes stored in a list
uint16_t myState; //!< Compact state: shape type(bits 0-3)+flags(bits 4-11)+reserved(bits 12-15)
};
#endif // _TopoDS_TShape_HeaderFile

View File

@@ -22,13 +22,6 @@ IMPLEMENT_STANDARD_RTTIEXT(TopoDS_TShell, TopoDS_TShape)
//=================================================================================================
TopAbs_ShapeEnum TopoDS_TShell::ShapeType() const
{
return TopAbs_SHELL;
}
//=================================================================================================
occ::handle<TopoDS_TShape> TopoDS_TShell::EmptyCopy() const
{
return occ::handle<TopoDS_TShell>(new TopoDS_TShell());

View File

@@ -19,7 +19,6 @@
#include <Standard.hxx>
#include <Standard_Type.hxx>
#include <TopAbs_ShapeEnum.hxx>
#include <TopoDS_TShape.hxx>
//! A set of faces connected by their edges.
@@ -28,11 +27,9 @@ class TopoDS_TShell : public TopoDS_TShape
public:
//! Creates an empty TShell.
TopoDS_TShell()
= default;
//! Returns SHELL.
Standard_EXPORT TopAbs_ShapeEnum ShapeType() const override;
: TopoDS_TShape(TopAbs_SHELL)
{
}
//! Returns an empty TShell.
Standard_EXPORT occ::handle<TopoDS_TShape> EmptyCopy() const override;

View File

@@ -22,13 +22,6 @@ IMPLEMENT_STANDARD_RTTIEXT(TopoDS_TSolid, TopoDS_TShape)
//=================================================================================================
TopAbs_ShapeEnum TopoDS_TSolid::ShapeType() const
{
return TopAbs_SOLID;
}
//=================================================================================================
occ::handle<TopoDS_TShape> TopoDS_TSolid::EmptyCopy() const
{
return occ::handle<TopoDS_TSolid>(new TopoDS_TSolid());

View File

@@ -19,7 +19,6 @@
#include <Standard.hxx>
#include <Standard_Type.hxx>
#include <TopAbs_ShapeEnum.hxx>
#include <TopoDS_TShape.hxx>
//! A Topological part of 3D space, bounded by shells,
@@ -28,10 +27,11 @@ class TopoDS_TSolid : public TopoDS_TShape
{
public:
//! Creates an empty TSolid.
TopoDS_TSolid() { Orientable(false); }
//! returns SOLID.
Standard_EXPORT TopAbs_ShapeEnum ShapeType() const override;
TopoDS_TSolid()
: TopoDS_TShape(TopAbs_SOLID)
{
Orientable(false);
}
//! Returns an empty TSolid.
Standard_EXPORT occ::handle<TopoDS_TShape> EmptyCopy() const override;

View File

@@ -18,10 +18,3 @@
#include <TopoDS_Shape.hxx>
IMPLEMENT_STANDARD_RTTIEXT(TopoDS_TVertex, TopoDS_TShape)
//=================================================================================================
TopAbs_ShapeEnum TopoDS_TVertex::ShapeType() const
{
return TopAbs_VERTEX;
}

View File

@@ -18,7 +18,6 @@
#define _TopoDS_TVertex_HeaderFile
#include <Standard.hxx>
#include <TopAbs_ShapeEnum.hxx>
#include <TopoDS_TShape.hxx>
// resolve name collisions with X11 headers
@@ -27,18 +26,16 @@
#endif
//! A Vertex is a topological point in two or three dimensions.
//! TVertex has no children (sub-shapes).
class TopoDS_TVertex : public TopoDS_TShape
{
public:
//! Returns VERTEX.
Standard_EXPORT TopAbs_ShapeEnum ShapeType() const override;
DEFINE_STANDARD_RTTIEXT(TopoDS_TVertex, TopoDS_TShape)
protected:
//! Construct a vertex.
TopoDS_TVertex()
: TopoDS_TShape(TopAbs_VERTEX)
{
Closed(true);
Convex(true);

View File

@@ -22,13 +22,6 @@ IMPLEMENT_STANDARD_RTTIEXT(TopoDS_TWire, TopoDS_TShape)
//=================================================================================================
TopAbs_ShapeEnum TopoDS_TWire::ShapeType() const
{
return TopAbs_WIRE;
}
//=================================================================================================
occ::handle<TopoDS_TShape> TopoDS_TWire::EmptyCopy() const
{
return occ::handle<TopoDS_TWire>(new TopoDS_TWire());

View File

@@ -19,7 +19,6 @@
#include <Standard.hxx>
#include <Standard_Type.hxx>
#include <TopAbs_ShapeEnum.hxx>
#include <TopoDS_TShape.hxx>
//! A set of edges connected by their vertices.
@@ -28,11 +27,9 @@ class TopoDS_TWire : public TopoDS_TShape
public:
//! Creates an empty TWire.
TopoDS_TWire()
= default;
//! Returns WIRE.
Standard_EXPORT TopAbs_ShapeEnum ShapeType() const override;
: TopoDS_TShape(TopAbs_WIRE)
{
}
//! Returns an empty TWire.
Standard_EXPORT occ::handle<TopoDS_TShape> EmptyCopy() const override;

View File

@@ -80,49 +80,6 @@ bool TopAbs::ShapeOrientationFromString(const char* const theOrientationString
return false;
}
//=======================================================================
// function : TopAbs_Compose
// purpose : Compose two orientations
//=======================================================================
TopAbs_Orientation TopAbs::Compose(const TopAbs_Orientation O1, const TopAbs_Orientation O2)
{
// see the composition table in the file TopAbs.cdl
static const TopAbs_Orientation TopAbs_Table_Compose[4][4] = {
{TopAbs_FORWARD, TopAbs_REVERSED, TopAbs_INTERNAL, TopAbs_EXTERNAL},
{TopAbs_REVERSED, TopAbs_FORWARD, TopAbs_INTERNAL, TopAbs_EXTERNAL},
{TopAbs_INTERNAL, TopAbs_INTERNAL, TopAbs_INTERNAL, TopAbs_INTERNAL},
{TopAbs_EXTERNAL, TopAbs_EXTERNAL, TopAbs_EXTERNAL, TopAbs_EXTERNAL}};
return TopAbs_Table_Compose[(int)O2][(int)O1];
}
//=======================================================================
// function : TopAbs::Reverse
// purpose : reverse an Orientation
//=======================================================================
TopAbs_Orientation TopAbs::Reverse(const TopAbs_Orientation Ori)
{
static const TopAbs_Orientation TopAbs_Table_Reverse[4] = {TopAbs_REVERSED,
TopAbs_FORWARD,
TopAbs_INTERNAL,
TopAbs_EXTERNAL};
return TopAbs_Table_Reverse[(int)Ori];
}
//=======================================================================
// function : TopAbs::Complement
// purpose : complement an Orientation
//=======================================================================
TopAbs_Orientation TopAbs::Complement(const TopAbs_Orientation Ori)
{
static const TopAbs_Orientation TopAbs_Table_Complement[4] = {TopAbs_REVERSED,
TopAbs_FORWARD,
TopAbs_EXTERNAL,
TopAbs_INTERNAL};
return TopAbs_Table_Complement[(int)Ori];
}
//=======================================================================
// function : TopAbs_Print
// purpose : print the name of a State on a stream.

View File

@@ -66,10 +66,18 @@ public:
//! EXTERNAL | EXTERNAL EXTERNAL EXTERNAL EXTERNAL
//! Note: The top corner in the table is the most important
//! for the purposes of Open CASCADE topology and shape sharing.
Standard_EXPORT static TopAbs_Orientation Compose(const TopAbs_Orientation Or1,
const TopAbs_Orientation Or2);
static TopAbs_Orientation Compose(const TopAbs_Orientation Or1,
const TopAbs_Orientation Or2) noexcept
{
static constexpr TopAbs_Orientation aTable[4][4] = {
{TopAbs_FORWARD, TopAbs_REVERSED, TopAbs_INTERNAL, TopAbs_EXTERNAL},
{TopAbs_REVERSED, TopAbs_FORWARD, TopAbs_INTERNAL, TopAbs_EXTERNAL},
{TopAbs_INTERNAL, TopAbs_INTERNAL, TopAbs_INTERNAL, TopAbs_INTERNAL},
{TopAbs_EXTERNAL, TopAbs_EXTERNAL, TopAbs_EXTERNAL, TopAbs_EXTERNAL}};
return aTable[static_cast<int>(Or2)][static_cast<int>(Or1)];
}
//! xchanges the interior/exterior status of the two
//! Exchanges the interior/exterior status of the two
//! sides. This is what happens when the sense of
//! direction is reversed. The following rules apply:
//!
@@ -79,7 +87,14 @@ public:
//! EXTERNAL EXTERNAL
//!
//! Reverse exchange the material sides.
Standard_EXPORT static TopAbs_Orientation Reverse(const TopAbs_Orientation Or);
static TopAbs_Orientation Reverse(const TopAbs_Orientation Or) noexcept
{
static constexpr TopAbs_Orientation aTable[4] = {TopAbs_REVERSED,
TopAbs_FORWARD,
TopAbs_INTERNAL,
TopAbs_EXTERNAL};
return aTable[static_cast<int>(Or)];
}
//! Reverses the interior/exterior status of each side of
//! the object. So, to take the complement of an object
@@ -94,7 +109,14 @@ public:
//!
//! Complement complements the material side.
//! Inside becomes outside.
Standard_EXPORT static TopAbs_Orientation Complement(const TopAbs_Orientation Or);
static TopAbs_Orientation Complement(const TopAbs_Orientation Or) noexcept
{
static constexpr TopAbs_Orientation aTable[4] = {TopAbs_REVERSED,
TopAbs_FORWARD,
TopAbs_EXTERNAL,
TopAbs_INTERNAL};
return aTable[static_cast<int>(Or)];
}
//! Prints the name of Shape type as a String on the Stream.
static Standard_OStream& Print(const TopAbs_ShapeEnum theShapeType, Standard_OStream& theStream)