AMCAX Kernel 1.0.0.0
Loading...
Searching...
No Matches
Construction of Topological Structures​

MakeShape

Quickly creating topological structures is a basic requirement, and functions like AMCAX::MakeVertex, AMCAX::MakeEdge, AMCAX::MakeWire, AMCAX::MakeFace, etc., provide quick creation methods for different topological structures. These are commonly used and important functionalities.

MakeVertex

A Vertex can be created with a Point3:

AMCAX::Point3 p1(1.,2.,3.);
Class of making a vertex.
Definition MakeVertex.hpp:18
Class of vertex.
Definition TopoVertex.hpp:12
PointT< double, 3 > Point3
3D point
Definition PointT.hpp:459

MakeEdge

AMCAX::MakeEdge can quickly create an Edge based on a Curve. If no Vertex is provided in the input for MakeEdge, it will automatically create two Vertices. This means that if you want to create two connected Edges using MakeEdge, you must pay attention to the shared Vertex. A simple construction will result in two Edges and four Vertices. Additionally, degenerated edges can also be created using MakeEdge. MakeEdge has many functionalities, and we will introduce them categorically:

Simple Construction

You can create a line segment Edge using two Point3s or two TopoVertices. Note that the distance between the two Point3s/TopoVertices must be greater than AMCAX::Precision::Confusion(), otherwise, they will be considered the same Point3/TopoVertex.

//Make an edge between two points
AMCAX::Point3 p1(0., 0., 0.);
AMCAX::Point3 p2(1.0, 0.0, 0.0);
//Make an edge between two vertices
Class of making an edge.
Definition MakeEdge.hpp:26
Class of edge.
Definition TopoEdge.hpp:12

Based on Mathematical Expressions

For example, you can build it based on Line3, Circle3, etc. Here’s an example using Line3:

AMCAX::Point3 p1(0., 0., 0.);
AMCAX::Point3 p2(1.0, 0.0, 0.0);
//Create a 3D line
AMCAX::Line3 line(p1, AMCAX::Direction3(1.0, 0.0, 0.0));
// Infinite length
// Set parameter range
AMCAX::TopoEdge edge2 = AMCAX::MakeEdge(line, 0.0, 1.0);
// Set first and last point
AMCAX::TopoEdge edge3 = AMCAX::MakeEdge(line, p1, p2);
// Set first and last vertex
AMCAX::TopoEdge edge4 = AMCAX::MakeEdge(line, v1, v2);
LineS< 3 > Line3
3D line
Definition LineT.hpp:457
DirectionT< double, 3 > Direction3
3D direction
Definition DirectionT.hpp:566

MakeEdge will automatically adjust parameters, Point3, and Vertex order based on the mathematical expression:

AMCAX::TopoEdge edge7 = AMCAX::MakeEdge(line, 1.0, 0.0); // same as MakeEdge(line, 0.0, 1.0)
AMCAX::TopoEdge edge8 = AMCAX::MakeEdge(line, p2, p1); // same as MakeEdge(line, p1, p2)
AMCAX::TopoEdge edge9 = AMCAX::MakeEdge(line, v2, v1); // same as MakeEdge(line, v1, v2)

Based on 3D Curve

This is an important functionality for building Edges from curves. Here, MakeEdge will still automatically adjust parameters, Point3, and Vertex order, as well as Vertex orientation.

AMCAX::Point3 p1(0., 0., 0.);
AMCAX::Point3 p2(1.0, 0.0, 0.0);
//Create a 3D line
AMCAX::Line3 line(p1, AMCAX::Direction3(1.0, 0.0, 0.0));
//Get curve
std::shared_ptr<AMCAX::Geom3Curve> curve = std::make_shared<AMCAX::Geom3Line>(line);
// Infinite length
// Set parameter range
AMCAX::TopoEdge edge2 = AMCAX::MakeEdge(curve, 0.0, 1.0);
// Set first and last point
AMCAX::TopoEdge edge3 = AMCAX::MakeEdge(curve, p1, p2);
// Set first and last point and parameter range
AMCAX::TopoEdge edge4 = AMCAX::MakeEdge(curve, p1, p2, 0.0, 1.0);
// Set first and last vertex
AMCAX::TopoEdge edge5 = AMCAX::MakeEdge(curve, v1, v2);
// Set first and last vertex and parameter range
AMCAX::TopoEdge edge6 = AMCAX::MakeEdge(curve, v1, v2, 0.0, 1.0);

Based on pcurve

It is important to note that Edges created based on pcurve and Surface do not have 3D curves. Here's how you can construct them:

AMCAX::Point3 p1(0., 0., 0.);
AMCAX::Point3 p2(1.0, 0.0, 0.0);
std::shared_ptr<AMCAX::Geom2Curve> pcurve = std::make_shared<AMCAX::Geom2Line>(); // ox2d
std::shared_ptr<AMCAX::Geom3Surface> surf = std::make_shared<AMCAX::Geom3Plane>(); // xoy
// Infinite length
AMCAX::TopoEdge edge1 = AMCAX::MakeEdge(pcurve, surf);
// Set parameter range
AMCAX::TopoEdge edge2 = AMCAX::MakeEdge(pcurve, surf, 0.0, 1.0);
// Set first and last point
AMCAX::TopoEdge edge3 = AMCAX::MakeEdge(pcurve, surf, p1, p2);
// Set first and last point and parameter range
AMCAX::TopoEdge edge4 = AMCAX::MakeEdge(pcurve, surf, p1, p2, 0.0, 1.0);
// Set first and last vertex
AMCAX::TopoEdge edge5 = AMCAX::MakeEdge(pcurve, surf, v1, v2);
// Set first and last vertex and parameter range
AMCAX::TopoEdge edge6 = AMCAX::MakeEdge(pcurve, surf, v1, v2, 0.0, 1.0);

MakeWire

A wire can be constructed in the following two ways:

Add Edge Individually

AMCAX::TopoEdge e1 = AMCAX::MakeEdge(AMCAX::Point3(-4., -1.0, 0.0), AMCAX::Point3(4., -1.0, 0.0));
AMCAX::TopoEdge e2 = AMCAX::MakeEdge(AMCAX::Point3(4., -1.0, 0.0), AMCAX::Point3(4., 1.0, 0.0));
AMCAX::TopoEdge e3 = AMCAX::MakeEdge(AMCAX::Point3(4., 1.0, 0.0), AMCAX::Point3(-4., 1.0, 0.0));
AMCAX::TopoEdge e4 = AMCAX::MakeEdge(AMCAX::Point3(-4., 1.0, 0.0), AMCAX::Point3(-4., -1.0, 0.0));
AMCAX::MakeWire makewire;
makewire.Add(e1);
makewire.Add(e2);
makewire.Add(e3);
makewire.Add(e4);
AMCAX::TopoWire w = makewire.Wire();
//Error
AMCAX::MakeWire makewire2;
makewire2.Add(e1);
makewire2.Add(e3);
std::cout << makewire2.IsDone() << std::endl;//1
std::cout << "error type:" << int(makewire2.Error());//0
Class of making a wire.
Definition MakeWire.hpp:19
AMCAX_API const TopoWire & Wire()
Get the constructed wire.
AMCAX_API WireError Error() const noexcept
Get the error status.
AMCAX_API void Add(const TopoEdge &e)
Add an edge to the wire.
AMCAX_API bool IsDone() const noexcept override
Is the construction algorithm done.
Class of wire.
Definition TopoWire.hpp:12

Note: Each edge added must geometrically connect to the edge that has already been added. For the example above, if the edges are added in the order e1—e3—e2—e4, when e3 is added, it will fail because it is not connected to e1. In this case, calling IsDone() will return false, and calling Error() will return WireError::DisconnectedWire. If it is known that the edges to be connected into a wire are connected, but the exact connection order is unknown, then the edge list method described below should be used.

Add a List of Edge

The order of edges in the list will not affect the result of the wire construction.

AMCAX::TopoEdge e1 = AMCAX::MakeEdge(AMCAX::Point3(0.0, 0.0, 0.0), AMCAX::Point3(1.0, 0.0, 0.0));
AMCAX::TopoEdge e2 = AMCAX::MakeEdge(AMCAX::Point3(1.0, 0.0, 0.0), AMCAX::Point3(1.0, 1.0, 0.0));
AMCAX::TopoEdge e3 = AMCAX::MakeEdge(AMCAX::Point3(1.0, 1.0, 0.0), AMCAX::Point3(0.0, 1.0, 0.0));
AMCAX::TopoEdge e4 = AMCAX::MakeEdge(AMCAX::Point3(0.0, 1.0, 0.0), AMCAX::Point3(0.0, 0.0, 0.0));
//Store edges in a list
std::list<AMCAX::TopoShape> elist = { e1, e3, e2, e4 };
//Add elist to wire
AMCAX::MakeWire makewire;
makewire.Add(elist);
//Get the wire
AMCAX::TopoWire wire = makewire.Wire();

Note: MakeWire can construct a wire that does not contain Seam Edges or degenerate edges. It supports adding individual edges or an edge list. MakeWire cannot correctly construct a wire containing degenerate edges because it determines orientation based on the 3D positions of the vertices, and degenerate edges have identical vertices, which may result in incorrect orientation. MakeWire also cannot correctly construct a wire containing non-manifold vertices, as this interface requires that the degree of vertices within a wire must be 2 (or 1, for open wire endpoints).

Add Wire

When adding a wire, its first edge must connect to the existing wire; otherwise the operation will fail.

void CheckWire(const AMCAX::MakeWire& mkWire)
{
std::cout << "MakeWire IsDone: " << std::boolalpha << mkWire.IsDone()
<< ", error: " << int(mkWire.Error()) << std::endl;
}
//wire123
AMCAX::Point3 p1(10., 0., 0.);
AMCAX::Point3 p2(15., 5., 0.);
AMCAX::Point3 p3(15., 10., 0.);
AMCAX::Point3 p4(10., 15., 0.);
AMCAX::TopoWire wire123 = AMCAX::MakeWire(e1, e2, e3).Wire();
//edge4
AMCAX::Point3 p5(5., 15., 0.);
//wire567
AMCAX::Axis3 axis(AMCAX::Point3(7.5, 0., 0.), AMCAX::Direction3(0., 1., 0.));
AMCAX::TopoShape tempshape = AMCAX::TransformShape(wire123, trans);
wire567.Reverse();
//edge8
AMCAX::Point3 p8(5., 0., 0.);
//Make wire
AMCAX::MakeWire mkWire(wire123);
mkWire.Add(edge8);
mkWire.Add(wire567);
CheckWire(mkWire);
//Error
AMCAX::MakeWire mkWire2(wire123);
mkWire2.Add(edge4);
mkWire2.Add(wire567);
CheckWire(mkWire2);
AMCAX_API const TopoEdge & Edge()
Get the constructed edge.
static AMCAX_API const TopoWire & Wire(const TopoShape &s)
Cast shape to wire.
Base class of shape, containing an underlying shape with a location and an orientation.
Definition TopoShape.hpp:15
AMCAX_API void Reverse() noexcept
Reverse the orientation of the shape.
Class of transforming a shape.
Definition TransformShape.hpp:12
void SetRotation(const PointT< OtherScalar, DIM > &point, const OtherScalar2 &angle) noexcept
Set the transformation as rotation around a point with an angle in 2D.
Definition TransformationT.hpp:138
constexpr double pi
Mathematical constant Pi, ratio of a circle's circumference to its diameter.
Definition Constants.hpp:42
AxisT< double, 3 > Axis3
3D axis
Definition AxisT.hpp:423
TransformationT< double, 3 > Transformation3
3D transformation
Definition TransformationT.hpp:1115

In this example, if edge4 is added to the existing wire before adding wire567, calling IsDone() will return false and Error() will return WireError::DisconnectedWire.

MakeFace

AMCAX::MakeFace has many functionalities, which we will introduce categorically:

Based on Mathematical Expression

t can be constructed based on mathematical expressions such as Plane, Cylinder, etc.:

AMCAX::TopoFace face1 = AMCAX::MakeFace(plane, 0.0, 1.0, 0.0, 1.0);
Class of making a face.
Definition MakeFace.hpp:24
Class of Plane.
Definition Plane.hpp:13
Class of face.
Definition TopoFace.hpp:12

Based on Surface

Constructing a face from a Geom3Surface is the most common functionality of MakeFace:

std::shared_ptr<AMCAX::Geom3Surface> surface = std::make_shared<AMCAX::Geom3Plane>();
AMCAX::TopoFace face2 = AMCAX::MakeFace(surface, 0.0, 1.0, 0.0, 1.0, AMCAX::Precision::Confusion());
static constexpr double Confusion() noexcept
Get the confusion tolerance.
Definition Precision.hpp:122

MakeFace requires providing tolerance when providing a surface. It is important to note that if the input surface is infinite and there are no constrained parameter ranges, a wire will not be automatically generated. In other cases, a wire will be generated automatically.

Based on Wire

Single Wire

When the wire lies on a plane, a face can be successfully constructed by directly inputting the wire:

AMCAX::TopoWire wire = AMCAX::MakeWire(circleEdge);
CircleS< 3 > Circle3
3D circle
Definition CircleT.hpp:187
FrameT< double, 3 > Frame3
3D frame
Definition FrameT.hpp:887

Note: Inputting a wire that does not lie on a plane may result in failure.

Wire + Mathematical Expression

Note: The final boolean parameter indicates whether the face region is inside the wire (true means inside).

Wire + Surface

AMCAX::TopoWire wire = AMCAX::MakeWire(circleEdge);
std::shared_ptr<AMCAX::Geom3Surface> surface = std::make_shared<AMCAX::Geom3Plane>();
AMCAX::TopoFace face7 = AMCAX::MakeFace(surface, wire, true);

Wire + Face

Adding a wire to an existing face:

AMCAX::TopoWire wire = AMCAX::MakeWire(circleEdge);
std::shared_ptr<AMCAX::Geom3Surface> surface = std::make_shared<AMCAX::Geom3Plane>();
AMCAX::TopoFace face7 = AMCAX::MakeFace(surface, wire, true);
AMCAX::Frame3 frame2(AMCAX::Point3(), AMCAX::Direction3(0.0, 0.0, -1.0));
AMCAX::TopoEdge circleEdge2 = AMCAX::MakeEdge(AMCAX::Circle3(frame2, 0.5));
AMCAX::TopoWire wire2 = AMCAX::MakeWire(circleEdge2);
AMCAX::TopoFace face8 = AMCAX::MakeFace(face7, wire2);

After execution, the result is as shown in the figure below: the left side is face7, and the right side is face8.

However, it is important to note the orientation of the wire. For example, if the code is written as below, it will produce an incorrect result:

The correct approach is to set the orientation of the edge or wire to Reversed at the edge or wire level.

AMCAX::TopoWire wire2 = AMCAX::MakeWire(circleEdge2);
AMCAX::TopoFace face8 = AMCAX::MakeFace(face7, AMCAX::TopoCast::Wire(wire2.Oriented(AMCAX::OrientationType::Reversed)));
AMCAX_API TopoShape Oriented(OrientationType orient) const noexcept
Get the shape with given orientation.

TopoBuilder

Although Make*.hpp provides some convenient APIs for building TopoShapes, certain modeling problems can only be solved by TopoBuilder. In this section, we will introduce the methods for constructing different topological structures using TopoBuilder.

Vertex

AMCAX::TopoBuilder::MakeVertex provides functionality to create a vertex.

// method 1
builder.MakeVertex(v, p, tol);
// method 2
builder.MakeVertex(v);
builder.UpdateVertex(v, p, tol);
Class of a tool for building B-Rep structure.
Definition TopoBuilder.hpp:39
AMCAX_API void MakeVertex(TopoVertex &v) const
Make an empty vertex.
AMCAX_API void UpdateVertex(const TopoVertex &v, const Point3 &p, double tol) const
Update the point of a vertex.

Edge

There are different methods to build different types of edges. We will introduce them one by one:

Ordinary Edge

The usual modeling approach is to calculate all the required Points, Curve3d, and PCurve using geometry, then build the topological structure:

Step 1: Prepare the Curve3d and construct the Edge using the curve.

AMCAX::MakeGeom3Line line(AMCAX::Point3(0.0, 0.0, 0.0), AMCAX::Direction3(1.0, 0.0, 0.0));
std::shared_ptr<AMCAX::Geom3Curve >curve = line.Value();
builder.MakeEdge(edge, curve, AMCAX::Precision::Confusion());
builder.Range(edge, 0.0, 2.0);
Class of making 3D geometric lines.
Definition MakeGeom3Line.hpp:15
AMCAX_API void MakeEdge(TopoEdge &e) const
Make an empty edge.
AMCAX_API void Range(const TopoEdge &e, double first, double last, bool only3d=false) const
Set the range of parameter of an edge.

AMCAX::TopoBuilder::Range sets the parameter range for the TopoEdge. If the parameter range of the curve matches the expected range of the edge, this step can be skipped.

Step 2: Prepare the start and end vertices and add them to the edge.

AMCAX::Point3 start(0.0, 0.0, 0.0);
AMCAX::Point3 last(2.0, 0.0, 0.0);
builder.MakeVertex(v1, start, tol);
builder.MakeVertex(v2, last, tol);
builder.Add(edge, v1);
//method 1
v2.SetOrientation(AMCAX::OrientationType::Reversed);
//method 2
v2.Reverse();
//method3
builder.Add(edge, v2.Oriented(AMCAX::OrientationType::Reversed));
AMCAX_API void Add(TopoShape &s, const TopoShape &c) const
Add a sub-shape to a shape.
AMCAX_API void SetOrientation(OrientationType orient) noexcept
Set the orientation of shape.

Note: Pay attention to the orientation of the start and end vertices. The orientation of the starting vertex is Forward, and the ending vertex is Reversed. The default orientation is Forward, so you need to change the orientation of the end vertex. There are two ways to do this: modify the orientation of the vertex itself or create a new one without modifying the original vertex. AMCAX::TopoShape::SetOrientation and AMCAX::TopoShape::Reverse modify the original vertex, while AMCAX::TopoShape::Oriented creates a new one and passes it to the builder.

Step 3: After constructing the Face, add the pcurve:

AMCAX::MakeGeom3Plane mp1(AMCAX::Point3(0., 0., 0.), AMCAX::Point3(0., 2., 0.), AMCAX::Point3(0., 2., 2.));
AMCAX::MakeGeom3Plane mp2(AMCAX::Point3(0., 0., 0.), AMCAX::Point3(2., 0., 0.), AMCAX::Point3(2., 2., 0.));
AMCAX::TopoFace face1 = AMCAX::MakeFace(mp1.Value(), 0.,2.,0.,2.,AMCAX::Precision::Confusion());
AMCAX::TopoFace face2 = AMCAX::MakeFace(mp2.Value(), 0.,2.,0.,2.,AMCAX::Precision::Confusion());
std::shared_ptr< AMCAX::Geom2Curve > pcurve1;
std::shared_ptr< AMCAX::Geom2Curve > pcurve2;
builder.UpdateEdge(edge, pcurve1, face1, AMCAX::Precision::PConfusion());
builder.UpdateEdge(edge, pcurve2, face2, AMCAX::Precision::PConfusion());
Class of making geometric planes.
Definition MakeGeom3Plane.hpp:13
static constexpr double PConfusion(double t) noexcept
Get the confusion tolerance in the 2D parametric space.
Definition Precision.hpp:127
AMCAX_API void UpdateEdge(const TopoEdge &e, const std::shared_ptr< Geom3Curve > &c, double tol) const
Update the curve and tolerance of an edge.

The direction of the pcurve should be consistent with the curve3d. The orientation of the edge does not affect the direction of the pcurve. Remember: "Geometry is geometry, topology is topology." The process of adding vertices can occur after creating the edge, so swapping steps 2 and 3 is fine. Adding vertices before calling Range is also acceptable.

Seam Edge

The steps are mostly the same, but with a slight variation in step 3:

builder.UpdateEdge(edge, pcurve1, pcurve2, face, Precision::PConfusion());

Note: The directions of pcurve1 and pcurve2 must remain consistent with the curve3d. pcurve1 corresponds to the Forward edge in the surface parameter domain, while pcurve2 corresponds to the Reversed edge in the surface parameter domain.

Degenerated Edge

Other steps are the same, but step 1 is different, as there is no curve3d:

builder.MakeEdge(edge);
builder.Degenerated(edge, true);
builder.Range(edge, 0.0, 2.0 * AMCAX::Constants::pi);
AMCAX_API void Degenerated(const TopoEdge &e, bool d) const
Set the degenerate flag of an edge.

Make sure to set the degenerated flag to True. The direction of the pcurve does not need to match the curve3d, just the orientation of the edge.

Free Edge

The steps remain the same, but step 3 differs, where only one pcurve is used.

Wire

The standard approach is:
Step 1: Determine the direction of the Wire based on the parameter domain, and identify which edges to use and their orientations:

std::vector<std::pair<int, bool>> wireEdges1 =
{
{1, true},
{2, true},
{3, true},
{4, true}
};

Step 2: Construct the Wire and add the edges:

builder.MakeWire(wire1);
for (const auto& edgeInfo : wireEdges1)
{
int edgeID = edgeInfo.first;
bool isForward = edgeInfo.second;
AMCAX::TopoShape crshape = allEdges[edgeID - 1];
if (isForward)
{
edge = AMCAX::TopoCast::Edge(crshape.Oriented(AMCAX::OrientationType::Forward));
}
else
{
edge = AMCAX::TopoCast::Edge(crshape.Oriented(AMCAX::OrientationType::Reversed));
}
builder.Add(wire1, edge);
}
AMCAX_API void MakeWire(TopoWire &w) const
Make an empty wire.
static AMCAX_API const TopoEdge & Edge(const TopoShape &s)
Cast shape to edge.

The order in which edges are added can be arbitrary.
Step 3: Set the closed flag for the Wire:

bool isClosedWire1 = AMCAX::TopoTool::IsClosed(wire1);
wire1.Closed(isClosedWire1);
AMCAX_API bool Closed() const noexcept
Is the shape closed.
static AMCAX_API bool IsClosed(const TopoShape &s)
Is the shape closed.

Face

To create a face, use the following method:

AMCAX::MakeGeom3Plane plane1(p1, -DZ);
builder.MakeFace(face1, plane1.Value(), AMCAX::Precision::Confusion());
builder.Add(face1, wire1);
static AMCAX_API const Direction3 & DZ() noexcept
Get the z-direction in 3D.
AMCAX_API void MakeFace(TopoFace &f) const
Make an empty face.

Shell

When constructing a shell, be mindful of the closed flag. The method is as follows:

builder.MakeShell(shell);
std::vector<AMCAX::TopoFace> allFaces = { face1 };
for (const auto& face : allFaces)
{
builder.Add(shell, face);
}
bool isClosedShell = AMCAX::TopoTool::IsClosed(shell);
shell.Closed(isClosedShell);
AMCAX_API void MakeShell(TopoShell &s) const
Make an empty shell.
Class of shell.
Definition TopoShell.hpp:12

Solid

To construct a solid, use this method:

builder.MakeSolid(solid);
builder.Add(solid, shell);
AMCAX_API void MakeSolid(TopoSolid &s) const
Make an empty solid.
Class of solid.
Definition TopoSolid.hpp:12

Compound

To create a compound, use this method:

builder.MakeCompound(comp);
builder.Add(comp, anyShape);
AMCAX_API void MakeCompound(TopoCompound &c) const
Make an empty compound.
Class of compound.
Definition TopoCompound.hpp:12