九韶内核 1.0.0.0
载入中...
搜索中...
未找到
拓扑结构的相关属性

Orientation

OrientationType 定义了四种方向类型:Forward、Reversed、Internal 和 External,其中 Forward 和 Reversed 是最常用的两种类型。在 TopoShape 的任何层级中,都可以通过以下方法操作方向属性:设置方向​:使用 SetOrientation() 方法;获取当前方向​:使用 Orientation() 方法;生成仅方向不同的新形状​:使用 Orientated() 方法。方向是 TopoShape 的一个独立属性,与几何(Geometry)和位置(Location)互不影响,修改其中任意一个属性,都不会对其他属性造成改变。

Vertex

对于一条 Edge ,其起始 Vertex 的 Orientation 为 Forward,终止 Vertex 的 Orientation 为 Reversed。比如一个线段 Edge 有两个不同的 Vertex,则 Orientation 一个是 Forward,另一个是 Reversed。再比如圆构成的 Edge 有两个相同的 Vertex,但 Orientation 也是一个为 Forward,另一个为 Reversed。

double r = 1.0; // radius
auto c = std::make_shared<AMCAX::Geom3Circle>(frame, r);
// Construct a vertex from a point
// Make an edge with a curve
builder.MakeEdge(edge, c, tol);
// Add vertices
builder.Add(edge, v1);
builder.Add(edge, v1.Oriented(AMCAX::OrientationType::Reversed));
std::cout << AMCAX::TopoTool::IsClosed(edge) << std::endl;// 1
创建顶点的类
定义 MakeVertex.hpp:18
static constexpr double Confusion() noexcept
获取混淆容差
定义 Precision.hpp:122
构造 B-Rep 结构的工具类
定义 TopoBuilder.hpp:39
AMCAX_API void MakeEdge(TopoEdge &e) const
构造空边
AMCAX_API void Add(TopoShape &s, const TopoShape &c) const
向形状中添加子形状
边的类
定义 TopoEdge.hpp:12
AMCAX_API TopoShape Oriented(OrientationType orient) const noexcept
获取指定方向后的形状
static AMCAX_API bool IsClosed(const TopoShape &s)
判断形状是否封闭
顶点类
定义 TopoVertex.hpp:12
PointT< double, 3 > Point3
三维点
定义 PointT.hpp:459
FrameT< double, 3 > Frame3
三维标架
定义 FrameT.hpp:887

注:在上面这个例子中,因为圆构成的 Edge 有两个相同的 Vertex,因此实际上只需构造一个 Vertex 即可完整定义该 Edge,这时调用 AMCAX::TopoTool::IsClosed(edge) 会返回 true。如果构造了两个顶点(坐标相同且方向相反),此时调用 AMCAX::TopoTool::IsClosed(edge) 会返回 false。

Edge

正向边(Forward)的方向与三维曲线(curve3d)的走向一致;若边无三维曲线,则正向边的方向与参数曲线(pcurve)的走向一致。反向边(Reversed)的方向与三维曲线(curve3d)的走向相反;若边无三维曲线,则反向边的方向与参数曲线(pcurve)的走向相反。

下面我们通过一个具体案例来演示边方向的重要性。在 XOY 平面上,通过三条三维曲线以及 Frame3(O, OZ, OX) 构建了一个三维几何平面:

在几何建模中,Wire 的方向直接影响了 Face 的有效构建。正常情况下,由于必须保证在参数域上,Wire 的方向是逆时针的,所以应当使用 Reversed 的 Edge0,Forward 的 Edge2,Forward 的 Edge1 构成 Wire。

如果构造了顺时针的 Wire ,即 Forward 的 Edge0,Reversed 的 Edge1,Reversed 的 Edge2,此时 Face 会定义为 Wire 不围成的部分。为直观展示这一特性,我们提供了对比图示:

若三维几何平面由 Frame3 (O, -OZ, OX) 构造而成,为确保 Face 能被正确定义为 Wire 所围成的区域,此时 Wire 的方向需为顺时针方向,即 Forward 的 Edge0,Reversed 的 Edge1,Reversed 的 Edge2。

Wire

对 Wire 执行 Reversed 操作会反转其方向。这一操作等价于:将 Wire 中所有 Edge 的 Orientation 变为反向(即原 Forward 变为 Reversed,原 Reversed 变为 Forward)。

// Make a box
AMCAX::Point3 p1(-5.0, -5.0, 0.0);// diagonal corner point
AMCAX::Point3 p2(5.0, 5.0, 3.0);// diagonal corner point
AMCAX::MakeBox box(p1, p2);
// Get the wire from box
AMCAX::TopoExplorerTool::MapShapes(box, AMCAX::ShapeType::Wire, wireSet);
// Get the edge from wire1
AMCAX::TopoExplorerTool::MapShapes(wire1, AMCAX::ShapeType::Edge, edgeSet);
std::cout << int(edge1.Orientation()) << std::endl;// 0
// Reverse the orientation of the wire1
// Get the edge from rewire1
AMCAX::TopoExplorerTool::MapShapes(rewire1, AMCAX::ShapeType::Edge, reedgeSet);
AMCAX::TopoEdge reedge1 = AMCAX::TopoCast::Edge(reedgeSet[0]);
std::cout << int(reedge1.Orientation()) << std::endl;// 1
创建立方体的类
定义 MakeBox.hpp:20
static AMCAX_API const TopoEdge & Edge(const TopoShape &s)
将形状转换为边
static AMCAX_API const TopoWire & Wire(const TopoShape &s)
将形状转换为环
static AMCAX_API void MapShapes(const TopoShape &s, ShapeType t, IndexSet< TopoShape > &shapeSet)
构造给定类型的子形状集合
AMCAX_API TopoShape Reversed() const noexcept
获取反转方向后的形状
AMCAX_API OrientationType Orientation() const noexcept
获取形状的方向
环类
定义 TopoWire.hpp:12

Face

对 Face 执行 Reversed 操作后,Face 所包围区域的方向,会变为该 Face 曲面法向的相反方向。这一操作等价于:将 Face 中所有 Wire 的 Orientation 变为反向(即原 Forward 变为 Reversed,原 Reversed 变为 Forward)。

// Make a box
AMCAX::Point3 p1(-5.0, -5.0, 0.0);// diagonal corner point
AMCAX::Point3 p2(5.0, 5.0, 3.0);// diagonal corner point
AMCAX::MakeBox box(p1, p2);
// Get the face from box
AMCAX::TopoExplorerTool::MapShapes(box, AMCAX::ShapeType::Face, faceSet);
std::cout << int(face1.Orientation()) << std::endl;// 1
// Get the wire from face1
AMCAX::TopoExplorerTool::MapShapes(face1, AMCAX::ShapeType::Wire, wireSet);
std::cout << int(wire1.Orientation()) << std::endl;// 1
// Reverse the orientation of the face1
std::cout << int(reface1.Orientation()) << std::endl;// 0
// Get the wire from reface1
AMCAX::TopoExplorerTool::MapShapes(reface1, AMCAX::ShapeType::Wire, rewireSet);
AMCAX::TopoWire rewire1 = AMCAX::TopoCast::Wire(rewireSet[0]);
std::cout << int(rewire1.Orientation()) << std::endl;// 0
static AMCAX_API const TopoFace & Face(const TopoShape &s)
将形状转换为面
面类
定义 TopoFace.hpp:12

获取 Face 所属曲面法向的方法如下:

// Get the surface of face1
std::shared_ptr< AMCAX::Geom3Surface > surface = AMCAX::TopoTool::Surface(face1, location);
// Compute the first partial derivatives at given parameters
double u = 0.5;
double v = 0.5;
surface->D1(u, v, p, du, dv);
// Calculate surface normal
AMCAX::Vector3 normal = du.Cross(dv);
std::cout << "normal:" << normal << std::endl;// 1 0 -0
virtual AMCAX_API void D1(double u, double v, Point3 &p, Vector3 &d1u, Vector3 &d1v) const =0
计算给定参数处的点和一阶偏导数
表示实体位置局部变换的类
定义 TopoLocation.hpp:14
static AMCAX_API const std::shared_ptr< Geom3Surface > & Surface(const TopoFace &f, TopoLocation &l)
获取面的曲面及曲面的位置
constexpr auto Cross(const VectorT< OtherScalar, DIM > &other) const noexcept
二维叉乘运算符
定义 VectorT.hpp:428
VectorT< double, 3 > Vector3
三维向量
定义 VectorT.hpp:707

Shell

对 Shell 执行 Reversed 操作会反转其方向。这一操作等价于:将 Shell 中所有 Face 的 Orientation 变为反向(即原 Forward 变为 Reversed,原 Reversed 变为 Forward)。

// Make a box
AMCAX::Point3 p1(-5.0, -5.0, 0.0);// diagonal corner point
AMCAX::Point3 p2(5.0, 5.0, 3.0);// diagonal corner point
AMCAX::MakeBox box(p1, p2);
// Get the shell from box
AMCAX::TopoShell shell = box.Shell();
// Get the face from shell
AMCAX::TopoExplorerTool::MapShapes(shell, AMCAX::ShapeType::Face, faceSet);
std::cout << int(face1.Orientation()) << std::endl;// 1
// Reverse the orientation of the shell
// Get the face from reshell
AMCAX::TopoExplorerTool::MapShapes(reshell, AMCAX::ShapeType::Face, refaceSet);
AMCAX::TopoFace reface1 = AMCAX::TopoCast::Face(refaceSet[0]);
std::cout << int(reface1.Orientation()) << std::endl;// 0
static AMCAX_API const TopoShell & Shell(const TopoShape &s)
将形状转换为壳体
壳体类
定义 TopoShell.hpp:12

Solid

对 Solid 执行 Reversed 操作会反转其方向。这一操作等价于:将 Solid 中所有 Shell 的 Orientation 变为反向(即原 Forward 变为 Reversed,原 Reversed 变为 Forward)。

// Make a box
AMCAX::Point3 p1(-5.0, -5.0, 0.0);// diagonal corner point
AMCAX::Point3 p2(5.0, 5.0, 3.0);// diagonal corner point
AMCAX::MakeBox box(p1,p2);
// Get the solid and shell from box
AMCAX::TopoSolid solid = box.Solid();
AMCAX::TopoShell shell = box.Shell();
std::cout << int(shell.Orientation()) << std::endl;// 0
// Reverse the orientation of the solid
// Get the shell from resolid
AMCAX::TopoExplorerTool::MapShapes(resolid, AMCAX::ShapeType::Shell, reshellSet);
AMCAX::TopoShell reshell = AMCAX::TopoCast::Shell(reshellSet[0]);
std::cout << int(reshell.Orientation()) << std::endl;// 1
static AMCAX_API const TopoSolid & Solid(const TopoShape &s)
将形状转换为实体
实体类
定义 TopoSolid.hpp:12

Tolerance

Tolerance 用于表示 TopoShape 的误差允许范围。例如,若某 Vertex 在 Edge1 的曲线上的对应点为 Point3 (0.0, 0.0, 0.0),在 Edge2 的曲线上的对应点为 Point3 (1.0, 0.0, 0.0),当 tolerance=2.0 时,这两个点会被视作同一点。也就是说,此类 Vertex 虽在不同 Edge 上的几何点不同,但作为拓扑结构,这个 Vertex 是合法的。
获取 TopoShape 的 Tolerance 可通过 AMCAX::TopoTool::Tolerance() 实现。仅 Vertex、Edge、Face 这类包含几何信息的结构具有 Tolerance 属性。若想更改 Tolerance 的可通过 UpdateVertex() ,UpdateEdge(),UpdateFace() 实现。

接下来我们将分别介绍 Vertex、Edge、Face 中的 Tolerance:

Vertex

Vertex 的 Tolerance 是一个设定值,其含义为:当 Point 到 Vertex 的距离(Point 到 Vertex 中 Point 的距离)不超过该 Tolerance 时,判定该点位于 Vertex 上。而 Vertex 的 Point 来源多样,包括其自身的 Point3、曲线(Curve)在某一参数下的值、曲面(Surface)在某一 uv 参数下的值等。需要注意的是,Vertex 的 Tolerance 必须不小于这些来源点之间的最大距离。

double r = 1.0;// radius
auto circle = std::make_shared<AMCAX::Geom3Circle>(frame, r);
// Get the first parameter
double fp = circle->FirstParameter();
// Get the first point
AMCAX::Point3 p1 = circle->Value(fp);
AMCAX::Point3 p2(0., 0., 0.);
// Make a vertex with a point , and the tolerance is 2.0
builder.MakeVertex(v1, p1, 2.0);
builder.MakeVertex(v2, p2, 2.0);
// Get the tolerance of a vertex
std::cout << AMCAX::TopoTool::Tolerance(v1);// 2.0
std::cout << AMCAX::TopoTool::Tolerance(v2);// 2.0
// Update the point of a vertex
double tol = 2.5;
builder.UpdateVertex(v1, p1, tol);
builder.UpdateVertex(v2, p2, tol);
std::cout << AMCAX::TopoTool::Tolerance(v1);// 2.5
std::cout << AMCAX::TopoTool::Tolerance(v2);// 2.5
AMCAX_API void MakeVertex(TopoVertex &v) const
构造空顶点
AMCAX_API void UpdateVertex(const TopoVertex &v, const Point3 &p, double tol) const
更新顶点的点
static AMCAX_API double Tolerance(const TopoFace &f)
获取面的容差

Edge

Edge 的 Tolerance 是一个设定值,其含义为:当 Point 到 Edge 的距离不超过该 Tolerance 时,判定该点位于 Edge 上。此外,Edge 有 curve3d 和 pcurve,其中 pcurve 可通过 Surface 构建一个等价的 curve3d。需要注意的是,多条 curve3d 在采样时的最大距离不得超过 Edge 的 Tolerance,若不满足这一条件,则必须增大 Edge 的 Tolerance。此外,Vertex 的 Tolerance 必须大于或等于其所在 Edge 的 Tolerance。

// Make a 3D circle
double r = 1.0;// radius
auto circle = std::make_shared<AMCAX::Geom3Circle>(frame, r);
// Get the first parameter
double fp = circle->FirstParameter();
// Get the first point
AMCAX::Point3 p1 = circle->Value(fp);
// Make a vertex with a point , and the tolerance is 2.0
AMCAX::Point3 p2(0., 0., 0.);
builder.MakeVertex(v1, p1, 2.0);
builder.MakeVertex(v2, p2, 2.0);
// Make an edge
AMCAX::MakeEdge e(v1, v2);
AMCAX::TopoEdge edge = e.Edge();
std::cout << AMCAX::TopoTool::Tolerance(edge);// 1e-7
// Update the tolerance
double tol = 1.0;
builder.UpdateEdge(edge, tol);
std::cout << AMCAX::TopoTool::Tolerance(edge);// 1.0
创建边的类
定义 MakeEdge.hpp:26
AMCAX_API void UpdateEdge(const TopoEdge &e, const std::shared_ptr< Geom3Curve > &c, double tol) const
更新边的三维曲线和容差

Face

Face 的 Tolerance 是一个设定值,其含义为:当 Point 到 Face 的距离不超过该 Tolerance 时,判定该点位于 Face 上,这一特性在布尔操作中应用较多。此外,Vertex 和 Edge 的 Tolerance 必须大于或等于其所在 Face 的 Tolerance。

// Make a face
AMCAX::Geom3Plane gplane(frame);
double uMin = 0.0;
double uMax = 2.0;
double vMin = 0.0;
double vMax = 2.0;
AMCAX::Plane plane = gplane.GetPlane();
AMCAX::TopoFace face = AMCAX::MakeFace(plane, uMin, uMax, vMin, vMax);
std::cout << AMCAX::TopoTool::Tolerance(face);// 1e-7
// Update the tolerance
double tol = 0.5;
builder.UpdateFace(face, tol);
std::cout << AMCAX::TopoTool::Tolerance(face);// 0.5
三维平面的类
定义 Geom3Plane.hpp:14
创建面的类
定义 MakeFace.hpp:24
平面类
定义 Plane.hpp:13
AMCAX_API void UpdateFace(const TopoFace &f, const std::shared_ptr< Geom3Surface > &s, const TopoLocation &l, double tol) const
更新面的曲面,位置和容差

注:当存在从属关系时,Vertex 的 Tolerance ≥ Edge 的 Tolerance ≥ Face 的 Tolerance。

Closed

TopoShape 是否封闭是一个关键标志(Flag)。我们可以使用 IsClosed() 来判断 TopoShape 是否封闭。这里需要与 Closed() 加以区分,Closed() 返回的布尔值是一个由用户自定义的标志。例如,将一条线段构建为一条 Edge,即便该 Edge 实际不封闭,仍可通过 Closed (true) 将其标志设为 true 。

// Make an edge
AMCAX::Point3 p0(0.0, 0.0, 0.0);
AMCAX::Point3 p1(1.0, 0.0, 0.0);
std::cout << AMCAX::TopoTool::IsClosed(edge) << std::endl;// 0
std::cout << edge.Closed() << std::endl;// 0
// Set the edge as closed
edge.Closed(true);
std::cout << edge.Closed() << std::endl;// 1
AMCAX_API bool Closed() const noexcept
判断形状是否封闭

而 IsClosed() 方法用于对特定类型的 TopoShape 进行拓扑上的判断。下文将逐一说明,当输入不同 ShapeType 的 TopoShape 时,IsClosed () 的具体用途。

Edge

IsClosed() 方法用于判断 Edge 的起始顶点与终止顶点是否为同一顶点(IsSame)。

// Construct a 3D circle
double r = 1.0;// radius
auto circle = std::make_shared<AMCAX::Geom3Circle>(frame, r);
// Construct an edge from a curve with two end vertices
AMCAX::Point3 p(1.0, 0.0, 0.0);
AMCAX::TopoEdge edge = AMCAX::MakeEdge(circle, v1, v1);
std::cout << AMCAX::TopoTool::IsClosed(edge) << std::endl;// 1
std::cout << edge.Closed() << std::endl;// 1

Wire

IsClosed() 方法用于判断 Wire 中是否不存在边界顶点,其判定逻辑为:遍历 Wire 中的所有顶点,每个顶点的出现次数均为偶数。

// Make a polygon
AMCAX::Point3 p1(-1., -1., 0.);// The first point
AMCAX::Point3 p2(1., -1., 0.);// The second point
AMCAX::Point3 p3(1., 1., 0.);// The third point
AMCAX::Point3 p4(-1., 1., 0.);// The fourth point
bool closed = true;
AMCAX::MakePolygon polygon(p1, p2, p3, p4, closed);
// Get the polygon wire
AMCAX::TopoWire wire = polygon.Wire();
std::cout << AMCAX::TopoTool::IsClosed(wire) << std::endl;//1
std::cout << wire.Closed() << std::endl;// 1
创建多边形的类
定义 MakePolygon.hpp:20

Shell

IsClosed () 方法用于判断 Shell 中是否不存在边界边(自由边),其判定逻辑为:遍历 Shell 中所有边,除退化边外,每条边的出现次数均为偶数。

// Make a box
double dx = 2.0;
double dy = 2.0;
double dz = 2.0;
AMCAX::MakeBox box(dx, dy, dz);
// Get the shell
AMCAX::TopoShell shell = box.Shell();
std::cout << AMCAX::TopoTool::IsClosed(shell) << std::endl;//1
std::cout << shell.Closed() << std::endl;// 1

其他

对 Solid、Face 类型执行 IsClosed() 的结果就是 Closed() 的结果。

// Make a box
double dx = 2.0;
double dy = 2.0;
double dz = 2.0;
AMCAX::MakeBox box(dx, dy, dz);
// Get the solid
AMCAX::TopoSolid solid = box.Solid();
std::cout << solid.Closed() << std::endl;// 1
std::cout << AMCAX::TopoTool::IsClosed(solid) << std::endl;// 1
// Set the shape as non-closed
solid.Closed(false);
std::cout << solid.Closed() << std::endl;// 0
std::cout << AMCAX::TopoTool::IsClosed(solid) << std::endl;// 0
// Get the face
AMCAX::TopoExplorerTool::MapShapes(box, AMCAX::ShapeType::Face, FaceSet);
std::cout << face1.Closed() << std::endl;// 0
std::cout << AMCAX::TopoTool::IsClosed(face1) << std::endl;// 0
// Set the shape as closed
face1.Closed(true);
std::cout << face1.Closed() << std::endl;//1
std::cout << AMCAX::TopoTool::IsClosed(face1) << std::endl;//1