MakeShape
快捷创建拓扑结构是一个基础需求,而 AMCAX::MakeVertex 、 AMCAX::MakeEdge 、 AMCAX::MakeWire 、 AMCAX::MakeFace 等提供了不同拓扑结构的快捷创建方式,这是非常常用也是非常重要的功能。
MakeVertex
创建 Vertex 可以通过一个 Point3 来创建:
创建顶点的类
定义 MakeVertex.hpp:16
PointT< double, 3 > Point3
三维点
定义 PointT.hpp:459
MakeEdge
AMCAX::MakeEdge 可以根据 Curve 快捷创建 Edge。如果 MakeEdge 的输入中没有 Vertex,那么 MakeEdge 会自动构建两个 Vertex。这意味着,如果想要用 MakeEdge 构建两条相连的 Edge,务必注意 Vertex 的共用问题,简单地构建只会得到 2 个 Edge 和 4 个 Vertex。此外,退化边也是可以用 MakeEdge 构建的。MakeEdge 功能众多,我们将分类介绍:
简单构建
可以通过两个 Point3 构建线段 Edge,也可以用两个 TopoVertex 构建。需要注意的是两个 Point3/TopoVertex 的距离要大于 AMCAX::Precision::Confusion(),否则就会被判断为同一个 Point3/TopoVertex。
基于数学表达构建
比如可以基于 Circle3,Line3 等数学表达构建,以下以 Line3 为例:
LineS< 3 > Line3
三维直线
定义 LineT.hpp:457
DirectionT< double, 3 > Direction3
三维方向
定义 DirectionT.hpp:587
另外 MakeEdge 会根据数学表达自动调整参数、Point3、Vertex 的顺序,以及 Vertex 的 Orientation:
基于curve 3d 构建
这是从 curve 构建 Edge 的重要功能。在这里 MakeEdge 仍然会自动调整参数、Point3、Vertex 的顺序,以及 Vertex 的 Orientation。构建方法如下:
std::shared_ptr<AMCAX::Geom3Curve> curve = std::make_shared<AMCAX::Geom3Line>(line);
基于 pcurve 构建
需要注意的是基于 pcurve 和 Surface 构建的 Edge 是没有 curve3d 的。构建方法如下:
std::shared_ptr<AMCAX::Geom2Curve> pcurve = std::make_shared<AMCAX::Geom2Line>();
std::shared_ptr<AMCAX::Geom3Surface> surf = std::make_shared<AMCAX::Geom3Plane>();
MakeWire
构建一个wire可以通过以下两种方式:
单独添加 Edge
std::cout << makewire2.
IsDone() << std::endl;
std::cout <<
"error type:" << int(makewire2.
Error());
AMCAX_API const TopoWire & Wire()
获取构造的环
AMCAX_API void Add(const TopoEdge &e)
向环中添加边
AMCAX_API WireError Error() const
获取构造过程中的错误状态
AMCAX_API bool IsDone() const override
判断构造算法是否完成
注:每次添加的边必须与之前已经添加的 edge 在几何上是相连的。如上面的例子,如果按照e1—e3—e2—e4的顺序进行添加,那么在添加 e3 的时候会因为不与 e1 相连导致添加不了,此时调用 IsDone() 会返回 false,调用 Error() 会返回 WireError::DisconnectedWire。如果能确定需要连成 wire 的 edge 是相连的,但不知道相连关系,那么必须使用下面一次性添加 edge list 的方式。
添加 Edge 的 list
列表中 edge 的顺序不会影响构造的结果。
std::list<AMCAX::TopoShape> elist = { e1, e3, e2, e4 };
注:MakeWire 能够构建不包含 Seam Edge、退化边的 Wire,支持单独添加 Edge 或添加 Edge的 list。MakeWire 不能正确构建含有退化边的wire,因为此接口会根据顶点 3D 点的几何位置来判断定向,而退化边的顶点是同一个,因此添加的退化边的定向可能不正确。MakeWire 不能正确构建含有非流形顶点的 wire,此接口要求在一个 wire 内的顶点的度数必须为2(或1,即开的 wire 端点)。
添加 wire
在添加 wire 时,要求 wire 中第一条 edge 与已有 wire 相连,才能 Add 成功。
{
std::cout <<
"MakeWire IsDone: " << std::boolalpha << mkWire.
IsDone()
<<
", error: " << int(mkWire.
Error()) << std::endl;
}
CheckWire(mkWire);
mkWire2.Add(edge4);
mkWire2.Add(wire567);
CheckWire(mkWire2);
AMCAX_API const TopoEdge & Edge()
获取构造的边
static AMCAX_API const TopoWire & Wire(const TopoShape &s)
将形状转换为环
形状的基类,包含具有位置和方向信息的基础形状
定义 TopoShape.hpp:15
AMCAX_API void Reverse()
反转形状的方向
constexpr double pi
数学常数 Pi,圆的周长与直径之比
定义 Constants.hpp:42
AxisT< double, 3 > Axis3
三维轴
定义 AxisT.hpp:423
TransformationT< double, 3 > Transformation3
三维变换
定义 TransformationT.hpp:1102
在该例子中,若在现有 wire 中添加了 edge4 后再添加 wire567,此时调用 IsDone() 会返回 false,调用 Error() 会返回 WireError::DisconnectedWire。
MakeFace
AMCAX::MakeFace 功能也很多,我们将分类进行介绍:
基于数学表达
可以基于 Plane,Cylinder 等数学表达构建:
基于Surface
基于 Geom3Surface 的 Face 构建是 MakeFace 最常用的功能:
std::shared_ptr<AMCAX::Geom3Surface> surface = std::make_shared<AMCAX::Geom3Plane>();
static constexpr double Confusion() noexcept
获取混淆容差
定义 Precision.hpp:122
MakeFace 要求在提供 Surface 的同时提供 Tolerance。需要注意的是,当输入的曲面为无穷大,且没有约束参数范围时,不会自动生成 Wire。其余情况都会自动生成 wire。
基于 Wire
单独 Wire
当 Wire 是平面上的 Wire 时,单独输入 Wire 构建 Face 是可以构建成功的:
CircleS< 3 > Circle3
三维圆
定义 CircleT.hpp:178
FrameT< double, 3 > Frame3
三维标架
定义 FrameT.hpp:885
注:输入不在平面上的 Wire 可能会构建失败。
Wire + 数学表达
注:需要提供 Face 表示的区域在 Wire 的内部还是外部(最后的 bool 参数,true 表示在内部)。
Wire + Surface
std::shared_ptr<AMCAX::Geom3Surface> surface = std::make_shared<AMCAX::Geom3Plane>();
Wire + Face
将 Wire 添加到 Face 中:
std::shared_ptr<AMCAX::Geom3Surface> surface = std::make_shared<AMCAX::Geom3Plane>();
执行后,结果如下图所示:左边为 face7,右图为 face8。
但是要注意 Wire 的 Orientation,也就是说,如果这样写,便会得到错误的结果:
而修正的方式是在 Edge 或 Wire 层级将其 Orientation 设为 Reversed:
AMCAX_API TopoShape Oriented(OrientationType orient) const
获取指定方向后的形状
TopoBuilder
尽管 Make*.hpp 提供了一些方便的构建 TopoShape 的 API,但是部分建模问题只有 TopoBuilder 能够解决。接下来我们将介绍 TopoBuilder 构建不同拓扑结构的方法。
Vertex
AMCAX::TopoBuilder::MakeVertex 提供构建一个顶点的功能。
构造 B-Rep 结构的工具类
定义 TopoBuilder.hpp:37
AMCAX_API void MakeVertex(TopoVertex &v) const
构造空顶点
AMCAX_API void UpdateVertex(const TopoVertex &v, const Point3 &p, double tol) const
更新顶点的点
Edge
针对不同类型的 Edge 有不同的构建方法。我们将逐一介绍:
普通 Edge
正常的建模思路是,通过几何计算得到了全部所需的 Point、Curve3d 和 PCurve,再构建拓扑结构:
第一步:准备好 Curve3d,根据 curve 构建 Edge。
std::shared_ptr<AMCAX::Geom3Curve >curve = line.Value();
builder.
Range(edge, 0.0, 2.0);
构造三维几何直线的类
定义 MakeGeom3Line.hpp:15
AMCAX_API void MakeEdge(TopoEdge &e) const
构造空边
AMCAX_API void Range(const TopoEdge &e, double first, double last, bool only3d=false) const
设置边的参数边界
AMCAX::TopoBuilder::Range 设置了 TopoEdge 的参数范围,如果 curve 的参数范围与 edge 期待的参数范围一致时,这一步可以省略。
第二步:准备起始 Vertex 和终止 Vertex,为 Edge 添加 Vertex。
builder.
Add(edge, v2.
Oriented(AMCAX::OrientationType::Reversed));
AMCAX_API void Add(TopoShape &s, const TopoShape &c) const
向形状中添加子形状
AMCAX_API void SetOrientation(OrientationType orient)
设置形状的方向
注:在这里要注意起始 Vertex 和终止 Vertex 的 Orientation。Edge 的起始 Vertex 是 Forward,终止 Vertex 是 Reversed。 Orientation 默认是 Forward ,所以需要对终止 Vertex 的 Orientation 进行改变。改变有两种形式:一是对自身进行改变,二是不对自身进行改变,产生一个新的。其中 AMCAX::TopoShape::SetOrientation 和 AMCAX::TopoShape::Reverse 对自身进行改变, AMCAX::TopoShape::Oriented 不对自身进行改变,而是产生一个新的,然后传入到 builder 里。
第三步:在构建好 Face 后,添加 pcurve:
std::shared_ptr< AMCAX::Geom2Curve > pcurve1;
std::shared_ptr< AMCAX::Geom2Curve > pcurve2;
构造三维几何平面的类
定义 MakeGeom3Plane.hpp:13
static constexpr double PConfusion(double t) noexcept
获取二维参数空间中的混淆容差
定义 Precision.hpp:127
AMCAX_API void UpdateEdge(const TopoEdge &e, const std::shared_ptr< Geom3Curve > &c, double tol) const
更新边的三维曲线和容差
要注意 pcurve 的方向应该与 curve3d 保持一致,edge 的 Orientation 对 pcurve 的方向没有任何影响,记住“几何是几何,拓扑是拓扑”。 而添加 Vertex 的步骤只要在 MakeEdge 后就可以,也就是说第二步第三步互换是没有问题的,在 Range 前添加 Vertex 也是没有问题的。
Seam Edge
其他的步骤都相同,仅第三步有所不同:
builder.
UpdateEdge(edge, pcurve1, pcurve2, face, Precision::PConfusion());
要注意 pcurve1、pcurve2 的方向仍然应该与 curve3d 保持一致。两个 pcurve 的区别是:pcurve1 是 Forward edge 在 Surface 参数域上的 pcurve,pcurve2 是 Reversed edge 在 Surface 参数域上的 pcurve。
Degenerated Edge
其他的步骤都相同,仅第一步不同,没有 curve3d:
AMCAX_API void Degenerated(const TopoEdge &e, bool d) const
设置边的退化标志
在这里要注意将退化 Flag 设为 True。而 pcurve 的方向无需考虑与 curve3d 保持一致,只需与 edge 的 Orientation 保持一致即可。
自由 Edge
其他的步骤都相同,仅第三步不同,只有 1 条 pcurve。
Wire
正常的思路是:
第一步先根据参数域上的 Wire 确定 Wire 的方向,再确定好选用哪些 Edge,这些 Edge 的 Orientation是什么:
std::vector<std::pair<int, bool>> wireEdges1 =
{
{1, true},
{2, true},
{3, true},
{4, true}
};
第二步构建并向 Wire 添加 Edge:
for (const auto& edgeInfo : wireEdges1)
{
int edgeID = edgeInfo.first;
bool isForward = edgeInfo.second;
if (isForward)
{
}
else
{
}
builder.
Add(wire1, edge);
}
AMCAX_API void MakeWire(TopoWire &w) const
构造一个空环
static AMCAX_API const TopoEdge & Edge(const TopoShape &s)
将形状转换为边
这里的 Edge 的添加顺序可以是任意的。
第三步将 Wire 的 Closed Flag 设置好:
AMCAX_API bool Closed() const
判断形状是否封闭
Face
构建 Face 的方法如下:
builder.
Add(face1, wire1);
static AMCAX_API const Direction3 & DZ() noexcept
获取三维中的 z 方向
AMCAX_API void MakeFace(TopoFace &f) const
构造一个空面
Shell
构建 Shell 时需要注意 Closed Flag,方法如下:
std::vector<AMCAX::TopoFace> allFaces = { face1 };
for (const auto& face : allFaces)
{
builder.
Add(shell, face);
}
AMCAX_API void MakeShell(TopoShell &s) const
构造一个空壳
Solid
构建 Solid 的方式如下:
builder.
Add(solid, shell);
AMCAX_API void MakeSolid(TopoSolid &s) const
构造一个空实体
Compound
构建 Compound 的方式如下:
builder.
Add(comp, anyShape);
AMCAX_API void MakeCompound(TopoCompound &c) const
构造一个空复合体
复合体的类
定义 TopoCompound.hpp:12