Overview
This tutorial provides the basic usage of AMCAX kernel to model a valve model.
Required Knowledge
The developers need to have some basic knowledge including the modern C++ programming language, 3D geometric modeling concepts, and the B-Rep topology structure. In specific, the AMCAX kernel is designed by using C++ 17 standard, and STL containers and algorithms are used as basic data structures and utilities. The geometric entities are represented by a Boundary-Representation (B-Rep) structure, including geometry objects and topology structures.
Model Preview
This tutorial uses a simplified valve model to show some of main modeling functionalities in the AMCAX kernel. The model is shown in the figure below:
The valve model.
The model consists of three sub-parts:
- The fixing structure at the inlet/outlet.
- The curved pipes for the passage of liquids.
- The block where a piston can be used to control the valve.
We will introduce the constructions step-by-step, and provide explanations in as much detail as possible.
Building the Hexagon Prism
Let's start with the inlet/outlet of the valve. A rounded-corner hexagon prism is created to represent the fixing structure.
Creating a Polygon
The first step is create a hexagon using the AMCAX::MakePolygon class. The resulting face can be constructed by using the AMCAX::MakeFace class.
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.
Definition MakeFace.hpp:22
Class of making a polygon.
Definition 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.
Definition TopoFace.hpp:12
Class of wire.
Definition TopoWire.hpp:12
VectorT< double, 3 > Vector3
3D vector
Definition VectorT.hpp:707
PointT< double, 3 > Point3
3D point
Definition PointT.hpp:459
Click here example1 to get the complete source code for the above example, which you can download according to your learning needs.
Applying 2D Fillets
To construct a round-corner hexagon, we apply a 2D fillet to each vertex of the hexagon by using the AMCAX::MakeFillet2d class.
for (
int i = 0; i < vertices.
size(); ++i)
{
}
Template class of indexed set.
Definition IndexSet.hpp:20
int size() const noexcept
Get the size of the set.
Definition IndexSet.hpp:84
Class of make fillet and chamfer on a vertex of a planar face.
Definition 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.
Definition TopoShape.hpp:15
In the above sample code, the AMCAX::IndexSet class is essentially an unordered set whose elements have their own indices. The AMCAX::TopoExplorerTool::MapShapes function will find all the vertices in the shape. Click here example2 to get the complete source code for the above example, which you can download according to your learning needs.
Extruding a Prism
Next, we extrude the hexagon to create a prism by using the AMCAX::MakePrism class.
Class of making a prism or an extrusion shape.
Definition MakePrism.hpp:16
Click here example3 to get the complete source code for the above example, which you can download according to your learning needs.
Applying 3D Chamfers
Then, we apply 3D chamfers by using AMCAX::MakeChamfer class.
{
{
makeChamfer.Add(0.5, edge);
}
}
The class of chamfer.
Definition MakeChamfer.hpp:20
static constexpr double Confusion() noexcept
Get the confusion tolerance.
Definition Precision.hpp:122
static AMCAX_API const TopoEdge & Edge(const TopoShape &s)
Cast shape to edge.
Class of edge.
Definition TopoEdge.hpp:12
Class of a tool for exploring the B-Rep structure.
Definition TopoExplorer.hpp:14
AMCAX_API bool More() const
Does the explorer have more shapes.
Class of vertex.
Definition TopoVertex.hpp:12
Here, the AMCAX::TopoExplorer class is used to traverse all the edges in the shape. And if an edge has two vertices sharing the same x coordinate, then we chamfer along the edge. Click here example4 to get the complete source code for the above example, which you can download according to your learning needs.
Building the Curved Pipe
Next, we create a curved pipe for inlet/outlet. The process seems a little bit complicated, but the main sub-steps are quite simple. The pipe is created by using the AMCAX::MakePipe class. This class requires a spine wire representing the sweeping path and a profile shape to be used to sweep.
Construct a Spine Wire
The spine wire is a 'S' type path, consisting of five curves: line – arc – line – arc – line. All the curves are G1 connected. This means that the middle line is tangent to both the arcs. Here, we first create 2D circles using the AMCAX::MakeGeom2Circle class, and then use the AMCAX::GccLine2Tangent class to find the line tangent to two circles.
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);
Class of adaptor of 2D geometric curves.
Definition AdaptorGeom2Curve.hpp:19
static AMCAX_API const Direction2 & DY2() noexcept
Get the y-direction in 2D.
static AMCAX_API GccQualifiedCircle Enclosing(const Circle2 &c)
Construct an enclosing circle.
static AMCAX_API GccQualifiedLine Outside(const Line2 &l)
Construct an outside line.
Class of constructing a 2D line tangent to two curves or points.
Definition GccLine2Tangent.hpp:19
Class of making 2D geometric circles.
Definition MakeGeom2Circle.hpp:13
LineS< 2 > Line2
2D line
Definition LineT.hpp:454
AxisT< double, 2 > Axis2
2D axis
Definition AxisT.hpp:420
PointT< double, 2 > Point2
2D point
Definition PointT.hpp:456
Then, we map the curves from 2D to 3D and build the five edges and the the spine wire. Here, the AMCAX::MakeArcOfCircle class is used to create arcs, the AMCAX::MakeSegment class is used to create line segments, the AMCAX::MakeEdge class is used to create edges from curves, and the AMCAX::MakeWire class is used to create the spine wire from edges.
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
Get the origin point in 3D.
static AMCAX_API const Direction3 & DY() noexcept
Get the y-direction in 3D.
static AMCAX_API const Direction3 & DX() noexcept
Get the x-direction in 3D.
static AMCAX_API Point3 To3d(const Frame3 &pos, const Point2 &p)
Convert a 2D point to a 3D point.
Class of making arcs of 3D circle.
Definition MakeArcOfCircle.hpp:17
Class of making an edge.
Definition MakeEdge.hpp:24
Class of making 3D line segments.
Definition MakeSegment.hpp:17
Class of making a wire.
Definition 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
3D line
Definition LineT.hpp:457
FrameT< double, 3 > Frame3
3D frame
Definition FrameT.hpp:885
Creating Profile Wires
The profile is a simple circle and is created by using the AMCAX::MakeGeom3Circle class.
Class of making 3D geometric circles.
Definition MakeGeom3Circle.hpp:13
DirectionT< double, 3 > Direction3
3D direction
Definition DirectionT.hpp:587
Creating 2D Offset Wire
Since the pipe is tunnel which has an inner face and an outer face, we create an offset shape for the profile of the outer face. The shape is copied by the AMCAX::CopyShape class, and then use the AMCAX::MakeOffset class to create a 2D offset wire.
offset.Perform(6.0);
if (offset.IsDone())
{
}
Class of copying a shape.
Definition CopyShape.hpp:12
Class of making offset wires.
Definition MakeOffset.hpp:19
static AMCAX_API const TopoWire & Wire(const TopoShape &s)
Cast shape to wire.
Creating Pipes
Next, we use the AMCAX::MakePipe class to create sweeping solids by using a face, generated by the AMCAX::MakeFace class, as the profile shape. We will compute a boolean cut of these two solid at the next step.
Class of make pipe algorithm.
Definition MakePipe.hpp:20
Click here example5 to obtain the complete source code for curved track pipe1, which you can download according to your learning needs. Click here example6 to obtain the complete source code for curved track pipe2, which you can download according to your learning needs.
Building the Valve
Finally, we build the central part of the valve, which is simplified to a cylinder where a piston can be used to control the valve.
Creating a Cylinder
A cylinder is created by using the AMCAX::MakeCylinder class.
static AMCAX_API const Direction3 & DZ() noexcept
Get the z-direction in 3D.
Class of making a cylinder.
Definition MakeCylinder.hpp:16
Click here example7 to get the complete source code for the above example, which you can download according to your learning needs.
Applying 3D Fillets
Here, we additionally add a small 3D fillet example to the middle cylinder by using the AMCAX::MakeFillet class as follows:
{
{
fillet.Add(1.0, edge);
}
}
middleCylinder = fillet.Shape();
The class of fillet.
Definition MakeFillet.hpp:23
Click here example8 to get the complete source code for the above example, which you can download according to your learning needs.
Mirroring the Curved Pipe
As the valve should have both the inlet and the outlet, we have to mirror the pipe by using the AMCAX::TransformShape class.
AxisT< double, 3 > Axis3
3D axis
Definition AxisT.hpp:423
TransformationT< double, 3 > Transformation3
3D transformation
Definition TransformationT.hpp:1102
Click here example9 to obtain the mirror curved track pipe1, the complete source code to construct pipe3, you can download according to your learning needs. Click here example10 to obtain the mirror curved track pipe2, to construct the complete source code of pipe4, you can download according to your learning needs. Click here example11 to obtain the mirror hex, construct hex2 complete source code, you can download according to your learning needs.
Boolean Operations
The final step is boolean all the parts together by using the AMCAX::BoolBRepFuse class and the AMCAX::BoolBRepCut class. Here shows the sample code:
The class of cut operation.
Definition BoolBRepCut.hpp:15
The class of fuse operation.
Definition BoolBRepFuse.hpp:15
Don't forget to construct a tunnel for pistons to contol the valve, although the construction is simplified to be a cylinder.
Meshing
After generated a shape, you may want to render the shape by modern rendering engines like OpenGL. Thus, we also provide a simple meshing tool to generate meshes for shapes.
Building Meshes
The AMCAX::BRepMeshIncrementalMesh class is often used to generate a mesh for each face in the shape. The edges have a polygon on mesh in each adjacent face, but the meshes only coincide at the boundary edges and are not topological connected. You can also use AMCAX::MakeShapeTool::EnsureNormalConsistency() to compute normals for vertices in the mesh. The sample code is as follows:
if (mesher.IsDone())
{
}
Class of meshing.
Definition BRepMeshIncrementalMesh.hpp:16
Exporting to a STL file
We provide tools for exporting meshes to STL files and OBJ files. Here is an example of exporting to a STL file.
Click here example12 to obtain the full source code of the entity modeling example, you can download it according to your needs.
Appendix
The complete code of this sample is listed here:
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 adaptor of 2D geometric curves.
Class of adaptor of 3D geometric surfaces.
The class of cut operation.
The class of fuse operation.
Class of Cartesian coordinate system.
Class of copying a shape.
Class of basic calculation for elementary curves.
Class of useful tools of constructing qualified curves.
Class of constructing a 2D line tangent to two curves or points.
Class of a curve with a qualifier used in gcc.
Class of 3D trimmed curve.
Template class of indexed set.
Class of making arcs of 3D circle.
Class of making a cylinder.
Class of make fillet and chamfer on a vertex of a planar face.
Class of making 2D geometric circles.
Class of making 3D geometric circles.
Class of making offset wires.
Class of making pipe algorithm.
Class of making a polygon.
Class of making 3D line segments.
Class of a tool for exploring the B-Rep structure.
Base class of shape, containing an underlying shape with a location and an orientation.