概述
本教程提供了 AMCAX 内核对阀门模型进行建模的基本用法。
所需知识
开发人员需要具备一些基础知识,包括现代 C++ 编程语言、3D 几何建模概念和 B-Rep 拓扑结构。具体来说,AMCAX 内核是使用 C++ 17 标准设计的,且使用 STL 容器和算法作为基本数据结构。几何实体由边界表示 (B-Rep) 结构表示,包括几何对象和拓扑结构。
模型预览
本教程使用简化的阀门模型来展示 AMCAX 内核中的一些主要建模功能。模型如下图所示:
阀门模型
该模型由三个子部分组成:
- 入口/出口处的固定结构。
- 用于液体通过的弯曲管道。
- 可放置活塞以控制阀门的缸体。
我们将逐步介绍这些结构,并尽可能详细地提供解释。
构建六棱柱
从阀门的入口/出口开始,首先创建一个圆角六棱柱来表示固定结构。
创建多边形
第一步是使用 AMCAX::MakePolygon 类创建一个六边形,然后可使用 AMCAX::MakeFace 类构造一个面。
int n = 6;
for (int i = 0; i < n; ++i)
{
double t = M_PI * 2.0 * i / n;
makePolygon.
Add(p1.Translated(
AMCAX::Vector3(0.0, std::cos(t), std::sin(t)) * 50.0));
}
Class of making a face
定义 MakeFace.hpp:22
Class of making a polygon
定义 MakePolygon.hpp:18
AMCAX_API void Close()
Close the polygon
AMCAX_API void Add(const Point3 &p)
Add a new point to the polygon
Class of face
定义 TopoFace.hpp:12
Class of wire
定义 TopoWire.hpp:12
VectorT< double, 3 > Vector3
三维向量
定义 VectorT.hpp:707
PointT< double, 3 > Point3
三维点
定义 PointT.hpp:459
点击这里example1可获得以上示例完整源码,大家根据学习需要自行下载。
应用 2D 圆角
为了构造一个圆角六边形,可使用 AMCAX::MakeFillet2d 类将 2D 圆角应用于六边形的每个顶点。
for (
int i = 0; i < vertices.
size(); ++i)
{
}
索引集的模板类
定义 IndexSet.hpp:20
int size() const noexcept
获取集合的大小
定义 IndexSet.hpp:99
在平面顶点上构造圆角和倒角的类
定义 MakeFillet2d.hpp:20
static AMCAX_API const TopoVertex & Vertex(const TopoShape &s)
Cast shape to vertex
Base class of shape, containing an underlying shape with a location and an orientation
定义 TopoShape.hpp:15
上面的示例代码使用了 AMCAX::IndexSet 类作为一个有序集合来存储六边形的所有顶点,而 AMCAX::TopoExplorerTool::MapShapes 函数可用于查找一个形状中的所有顶点。点击这里example2可获得以上示例完整源码,大家根据学习需要自行下载。
拉伸柱体
接下来,使用 AMCAX::MakePrism 类拉伸圆角六边形以创建棱柱。
Class of making a prism or an extrusion shape
定义 MakePrism.hpp:16
点击这里example3可获得以上示例完整源码,大家根据学习需要自行下载。
应用 3D 倒角
然后,使用 AMCAX::MakeChamfer 类应用 3D 倒角。
{
{
makeChamfer.Add(0.5, edge);
}
}
static constexpr double Confusion() noexcept
获取混淆容差
定义 Precision.hpp:122
static AMCAX_API const TopoEdge & Edge(const TopoShape &s)
Cast shape to edge
Class of edge
定义 TopoEdge.hpp:12
Class of a tool for exploring the B-Rep structure
定义 TopoExplorer.hpp:14
AMCAX_API bool More() const
Does the explorer have more shapes
Class of vertex
定义 TopoVertex.hpp:12
这里 AMCAX::TopoExplorer 类是用来遍历形状中的所有边。如果一条边有两个顶点具有相同的 x 坐标,就沿着这条边倒角。点击这里example4可获得以上示例完整源码,大家根据学习需要自行下载。
构建弯曲管道
下一步是创建一个连接入口和出口的弯曲管道。这个步骤稍微有些复杂,但核心步骤非常简单。管道实体是使用 AMCAX::MakePipe 类创建的,使用这个类需要先构建扫描路径和用于扫描的轮廓形状。
构建扫掠路径
扫掠路径是一个“S”型路径,由五条曲线组成:直线 – 圆弧 – 直线 – 圆弧 – 直线,其中所有曲线均为 G1 连接。这意味着中间的直线需要与两条圆弧相切。因此,首先用 AMCAX::MakeGeom2Circle 类创建 2D 圆,然后使用 AMCAX::GccLine2Tangent 类来构建与两个圆相切的直线。
if (!gcc.IsDone() || gcc.NSolutions() != 1)
{
throw AMCAX::ConstructionError();
}
double parSol1, parArg1, parSol2, parArg2;
gcc.Tangency1(0, parSol1, parArg1, pointSol1);
gcc.Tangency2(0, parSol2, parArg2, pointSol2);
二维几何曲线适配器的类
定义 AdaptorGeom2Curve.hpp:19
static AMCAX_API const Direction2 & DY2() noexcept
获取二维中的 y 方向
static AMCAX_API GccQualifiedCircle Enclosing(const Circle2 &c)
构造一个内切圆(在外)
static AMCAX_API GccQualifiedLine Outside(const Line2 &l)
构造一个外切直线
构造一条与两条曲线相切或经过两个点的二维直线的类
定义 GccLine2Tangent.hpp:19
构造二维几何圆的类
定义 MakeGeom2Circle.hpp:13
LineS< 2 > Line2
二维直线
定义 LineT.hpp:454
AxisT< double, 2 > Axis2
二维轴
定义 AxisT.hpp:420
PointT< double, 2 > Point2
二维点
定义 PointT.hpp:456
然后,将曲线从 2D 映射到 3D 并构建五条边来组成扫掠路径。这里 AMCAX::MakeArcOfCircle 类用于创建圆弧, AMCAX::MakeSegment 类用于创建线段, AMCAX::MakeEdge 类用于从曲线创建边, AMCAX::MakeWire 类用于从边创建路径。
std::shared_ptr<AMCAX::Geom3TrimmedCurve> arc1 =
AMCAX::MakeArcOfCircle(std::static_pointer_cast<AMCAX::Geom3Circle>(c13d)->Circle(), 0.0, parArg1,
true);
std::shared_ptr<AMCAX::Geom3TrimmedCurve> arc2 =
AMCAX::MakeArcOfCircle(std::static_pointer_cast<AMCAX::Geom3Circle>(c23d)->Circle(), 0.0, parArg2,
true);
std::shared_ptr<AMCAX::Geom3TrimmedCurve> seg1 =
AMCAX::MakeSegment(line, parSol1, parSol2);
makewire.
Add({e0, e1, e2, e3, e4});
static AMCAX_API const Point3 & Origin() noexcept
获取三维中的原点
static AMCAX_API const Direction3 & DY() noexcept
获取三维中的 y 方向
static AMCAX_API const Direction3 & DX() noexcept
获取三维中的 x 方向
static AMCAX_API Point3 To3d(const Frame3 &pos, const Point2 &p)
将二维点转换为三维点
构造三维圆弧的类
定义 MakeArcOfCircle.hpp:17
Class of making an edge
定义 MakeEdge.hpp:24
构造三维线段的类
定义 MakeSegment.hpp:17
Class of making a wire
定义 MakeWire.hpp:17
AMCAX_API const TopoWire & Wire()
Get the constructed wire
AMCAX_API void Add(const TopoEdge &e)
Add an edge to the wire
LineS< 3 > Line3
三维直线
定义 LineT.hpp:457
FrameT< double, 3 > Frame3
三维标架
定义 FrameT.hpp:885
创建轮廓线
轮廓线是由一个简单的圆构成,用 AMCAX::MakeGeom3Circle 类创建。
构造三维几何圆的类
定义 MakeGeom3Circle.hpp:13
DirectionT< double, 3 > Direction3
三维方向
定义 DirectionT.hpp:587
创建 2D 偏移线
由于管道是一个有内表面和外表面的隧道,因此需要为外表面的轮廓曲线0创建偏移曲线。先用 AMCAX::CopyShape 类复制轮廓线,然后使用 AMCAX::MakeOffset 类创建 2D 偏移曲线。
offset.Perform(6.0);
if (offset.IsDone())
{
}
Class of copying a shape
定义 CopyShape.hpp:12
Class of making offset wires
定义 MakeOffset.hpp:19
static AMCAX_API const TopoWire & Wire(const TopoShape &s)
Cast shape to wire
创建扫掠面
接下来,我们通过使用 AMCAX::MakeFace 类生成的面作为轮廓形状来创建扫描实体,构造扫描实体过程使用 AMCAX::MakePipe 类。在接下来步骤中,我们将计算这两个实体的布尔差。
Class of make pipe algorithm
定义 MakePipe.hpp:20
点击这里example5可获得弯曲轨道 pipe1 的完整源码,大家根据学习需要自行下载。 点击这里example6可获得弯曲轨道 pipe2 的完整源码,大家根据学习需要自行下载。
构建阀门
最后,我们构建阀门的中心部分,其被简化为一个空心的圆柱体,其内部可放置活塞用于控制阀门。
创建圆柱体
圆柱体是使用 AMCAX::MakeCylinder 类创建的。
static AMCAX_API const Direction3 & DZ() noexcept
获取三维中的 z 方向
Class of making a cylinder
定义 MakeCylinder.hpp:16
点击这里example7可获得以上示例完整源码,大家根据学习需要自行下载。
应用 3D 圆角
在这里,我们还使用 AMCAX::MakeFillet 类向圆柱体添加了一个小的 3D 圆角示例,如下所示:
{
{
fillet.Add(1.0, edge);
}
}
middleCylinder = fillet.Shape();
点击这里example8可获得以上示例完整源码,大家根据学习需要自行下载。
镜像弯曲管道
由于阀门应该同时具有入口和出口,因此我们必须使用 AMCAX::TransformShape 类来镜像管道。
AxisT< double, 3 > Axis3
三维轴
定义 AxisT.hpp:423
TransformationT< double, 3 > Transformation3
三维变换
定义 TransformationT.hpp:1102
点击这里example9可获得镜像弯曲轨道 pipe1 ,构造 pipe3 的完整源码,大家根据学习需要自行下载。 点击这里example10可获得镜像弯曲轨道 pipe2 ,构造 pipe4 完整源码,大家根据学习需要自行下载。 点击这里example11可获得镜像 hex ,构造 hex2 完整源码,大家根据学习需要自行下载。
布尔运算
最后一步是使用 AMCAX::BoolBRepFuse 类和 AMCAX::BoolBRepCut 类将所有部分通过布尔运算组合在一起。下面是示例代码:
切割运算的类
定义 BoolBRepCut.hpp:16
并集运算的类
定义 BoolBRepFuse.hpp:15
尽管结构被简化为一个圆柱体,不要忘记为中间的缸体构建一个通道,可通过放置活塞来控制阀门。
网格化
生成形状后,您可能希望通过现代渲染引擎(如 OpenGL)渲染形状。因此,本内核提供了一个简单的网格划分工具来生成模型的网格。
构建网格
AMCAX::BRepMeshIncrementalMesh 类通常用于为形状中的每个面生成网格。边在每个相邻面的网格上都有一个多段线表示,网格只在面的边界边重合,而没有拓扑连接。此外,还可以使用 AMCAX::MakeShapeTool::EnsureNormalConsistency() 来计算网格中顶点的法线。示例代码如下:
if (mesher.IsDone())
{
}
Class of meshing
定义 BRepMeshIncrementalMesh.hpp:16
导出到 STL 文件
本内核还提供用于将网格导出为 STL 文件和 OBJ 文件的工具。以下是导出到 STL 文件的示例。
点击这里example12可获得实体建模示例完整源码,大家根据学习需要自行下载。
附录
下面列出了此示例的完整代码:
void MakeValve()
{
int n = 6;
for (int i = 0; i < n; ++i)
{
double t = M_PI * 2.0 * i / n;
makePolygon.
Add(p1.Translated(
AMCAX::Vector3(0.0, std::cos(t), std::sin(t)) * 50.0));
}
for (
int i = 0; i < vertices.
size(); ++i)
{
}
{
{
makeChamfer.Add(0.5, edge);
}
}
if (!gcc.IsDone() || gcc.NSolutions() != 1)
{
throw AMCAX::ConstructionError();
}
double parSol1, parArg1, parSol2, parArg2;
gcc.Tangency1(0, parSol1, parArg1, pointSol1);
gcc.Tangency2(0, parSol2, parArg2, pointSol2);
std::shared_ptr<AMCAX::Geom3TrimmedCurve> arc1 =
AMCAX::MakeArcOfCircle(std::static_pointer_cast<AMCAX::Geom3Circle>(c13d)->Circle(), 0.0, parArg1,
true);
std::shared_ptr<AMCAX::Geom3TrimmedCurve> arc2 =
AMCAX::MakeArcOfCircle(std::static_pointer_cast<AMCAX::Geom3Circle>(c23d)->Circle(), 0.0, parArg2,
true);
std::shared_ptr<AMCAX::Geom3TrimmedCurve> seg1 =
AMCAX::MakeSegment(line, parSol1, parSol2);
makewire.
Add({e0, e1, e2, e3, e4});
offset.Perform(6.0);
if (offset.IsDone())
{
}
{
{
fillet.Add(1.0, edge);
}
}
middleCylinder = fillet.Shape();
if (mesher.IsDone())
{
}
}
Class of making a cylinder
Class of making offset wires
Class of making pipe algorithm
Class of making a polygon
Class of a tool for exploring the B-Rep structure
Base class of shape, containing an underlying shape with a location and an orientation