AMCAX Kernel 1.0.0.0
Loading...
Searching...
No Matches
Building Simple Models from the Bottom Up

Overview

This tutorial demonstrates bottom-up modeling techniques using a cube construction example.

The proper way to construct a cube is: first create 8 Vertices, then use these 8 Vertices to build 12 Edges, and finally use the Edges to construct Wires and Faces. Below are the numbering of the cube's Vertices, Edges, and Faces for your reference.

Note: The arrows in the image indicate the direction of the edges.

Build Cube

Build Vertex

std::vector<AMCAX::TopoShape> BuildBoxVertices()
{
// Define the 8 corner points of a box
std::vector<AMCAX::Point3> points;
points.push_back(AMCAX::Point3(0.5, -0.5, -0.5));
points.push_back(AMCAX::Point3(-0.5, -0.5, -0.5));
points.push_back(AMCAX::Point3(-0.5, 0.5, -0.5));
points.push_back(AMCAX::Point3(0.5, 0.5, -0.5));
points.push_back(AMCAX::Point3(0.5, -0.5, 0.5));
points.push_back(AMCAX::Point3(-0.5, -0.5, 0.5));
points.push_back(AMCAX::Point3(-0.5, 0.5, 0.5));
points.push_back(AMCAX::Point3(0.5, 0.5, 0.5));
std::vector<AMCAX::TopoShape> vertices;
for (const AMCAX::Point3& p : points)
{
vertices.push_back(v);
}
return vertices;
}
static constexpr double Confusion() noexcept
Get the confusion tolerance.
Definition Precision.hpp:122
Class of a tool for building B-Rep structure.
Definition TopoBuilder.hpp:39
AMCAX_API void MakeVertex(TopoVertex &v) const
Make an empty vertex.
Class of vertex.
Definition TopoVertex.hpp:12
PointT< double, 3 > Point3
3D point
Definition PointT.hpp:459

Build Edge

std::vector<AMCAX::TopoShape> BuildBoxEdges(const std::vector<AMCAX::TopoShape>& vertices)
{
// Vertex index pairs defining all box edges
std::vector<std::pair<int, int>> edgeVerticesID = { {0,1},{1,2},{2,3},{3,0},{4,5},{5,6},{6,7},{7,4},{0,4},{1,5},{2,6},{3,7} };
std::vector<AMCAX::TopoShape> edges;
for (const auto& [beginVID, endVID] : edgeVerticesID)
{
// Get oriented vertices (forward/reversed)
AMCAX::TopoVertex v1 = AMCAX::TopoCast::Vertex(vertices[beginVID].Oriented(AMCAX::OrientationType::Forward));
AMCAX::TopoVertex v2 = AMCAX::TopoCast::Vertex(vertices[endVID].Oriented(AMCAX::OrientationType::Reversed));
// Create 3D curve
AMCAX::Direction3 dir(p2.Coord() - p1.Coord());
std::shared_ptr<AMCAX::Geom3Curve> gline = std::make_shared<AMCAX::Geom3Line>(p1, dir);
// Build edge
builder.MakeEdge(edge, gline, AMCAX::Precision::Confusion());
builder.Add(edge, v1);
builder.UpdateVertex(v1, 0.0, edge, AMCAX::Precision::Confusion());
builder.Add(edge, v2);
builder.UpdateVertex(v2, p1.Distance(p2), edge, AMCAX::Precision::Confusion());
edges.push_back(edge);
}
return edges;
}
auto Distance(const PointT< OtherScalar, DIM > &other) const noexcept
Compute the Euclidean distance from the other point.
Definition PointT.hpp:180
constexpr const CoordType & Coord() const noexcept
Get the coordinate of point.
Definition PointT.hpp:151
AMCAX_API void MakeEdge(TopoEdge &e) const
Make an empty edge.
AMCAX_API void Add(TopoShape &s, const TopoShape &c) const
Add a sub-shape to a shape.
AMCAX_API void UpdateVertex(const TopoVertex &v, const Point3 &p, double tol) const
Update the point of a vertex.
static AMCAX_API const TopoVertex & Vertex(const TopoShape &s)
Cast shape to vertex.
Class of edge.
Definition TopoEdge.hpp:12
static AMCAX_API Point3 Point(const TopoVertex &v)
Get the point of a vertex.
DirectionT< double, 3 > Direction3
3D direction
Definition DirectionT.hpp:566

Important Note for Edge Construction:​ ​When adding vertices to an edge, you must explicitly set their orientation beforehand. The starting vertex of an edge should be assigned Forward orientation, while the ending vertex must use Reversed orientation.

Build Wire

std::vector<AMCAX::TopoShape> BuildBoxWires(const std::vector<AMCAX::TopoShape>& edges)
{
// Edge connectivity for each face wire: {edge index, orientation} pairs (true=forward, false=reversed)
std::vector<std::vector<std::pair<int, bool>>> wireEdgesVec =
{
{ {0,true},{1,true},{2,true},{3,true} },
{ {4,false},{7,false},{6,false},{5,false} },
{ {4,true},{9,false},{0,false},{8,true} },
{ {6,true},{11,false},{2,false},{10,true} },
{ {3,false},{11,true},{7,true},{8,false} },
{ {5,true},{10,false},{1,false},{9,true} }
};
std::vector<AMCAX::TopoShape> wires;
for (const auto& wireEdges : wireEdgesVec)
{
builder.MakeWire(wire);
for (const auto& [edgeID, isForward] : wireEdges)
{
// Add edge with proper orientation
AMCAX::TopoShape crshape = edges[edgeID];
if (isForward)
{
edge = AMCAX::TopoCast::Edge(crshape.Oriented(AMCAX::OrientationType::Forward));
}
else
{
edge = AMCAX::TopoCast::Edge(crshape.Oriented(AMCAX::OrientationType::Reversed));
}
builder.Add(wire, edge);
}
// Ensure wire closure
bool isClosedWire = AMCAX::TopoTool::IsClosed(wire);
wire.Closed(isClosedWire);
wires.push_back(wire);
}
return wires;
}
AMCAX_API void MakeWire(TopoWire &w) const
Make an empty wire.
static AMCAX_API const TopoEdge & Edge(const TopoShape &s)
Cast shape to edge.
Base class of shape, containing an underlying shape with a location and an orientation.
Definition TopoShape.hpp:15
AMCAX_API TopoShape Oriented(OrientationType orient) const noexcept
Get the shape with given orientation.
AMCAX_API bool Closed() const noexcept
Is the shape closed.
static AMCAX_API bool IsClosed(const TopoShape &s)
Is the shape closed.
Class of wire.
Definition TopoWire.hpp:12

When constructing wires, please note: All wires must follow a counter-clockwise (CCW) direction when viewed from the opposite direction of the face normal (i.e., looking from outside the solid toward the interior).

Build Face

std::vector<AMCAX::TopoShape> BuildBoxFaces(const std::vector<AMCAX::TopoShape>& wires)
{
// Create reference frames for each face plane
AMCAX::Frame3 frameBottom(AMCAX::Point3(0.0, 0.0, -0.5), -z, -x);
AMCAX::Frame3 frameTop(AMCAX::Point3(0.0, 0.0, 0.5), z, x);
AMCAX::Frame3 frameLeft(AMCAX::Point3(0.0, -0.5, 0.0), -y, -x);
AMCAX::Frame3 frameRight(AMCAX::Point3(0.0, 0.5, 0.0), y, x);
AMCAX::Frame3 frameFront(AMCAX::Point3(0.5, 0.0, 0.0), x, -z);
AMCAX::Frame3 frameBack(AMCAX::Point3(-0.5, 0.0, 0.0), -x, z);
std::vector<AMCAX::Frame3> planeFrames = { frameBottom,frameTop,frameLeft,frameRight,frameFront,frameBack };
// Create 3D plane
std::vector<std::shared_ptr<AMCAX::Geom3Plane>> planes;
for (const AMCAX::Frame3& frame : planeFrames)
{
planes.push_back(std::make_shared<AMCAX::Geom3Plane>(frame));
}
std::vector<AMCAX::TopoShape> faces;
for (int i = 0; i < static_cast<int>(wires.size()); i++)
{
//Make a face with a surface
builder.MakeFace(face, planes[i], AMCAX::Precision::Confusion());
builder.Add(face, wires[i]);
faces.push_back(face);
}
return faces;
}
static AMCAX_API const Direction3 & DY() noexcept
Get the y-direction in 3D.
static AMCAX_API const Direction3 & DZ() noexcept
Get the z-direction in 3D.
static AMCAX_API const Direction3 & DX() noexcept
Get the x-direction in 3D.
AMCAX_API void MakeFace(TopoFace &f) const
Make an empty face.
Class of face.
Definition TopoFace.hpp:12
FrameT< double, 3 > Frame3
3D frame
Definition FrameT.hpp:887

Build Shell

std::vector<AMCAX::TopoShape> vertices = BuildBoxVertices();
std::vector<AMCAX::TopoShape> edges = BuildBoxEdges(vertices);
std::vector<AMCAX::TopoShape> wires = BuildBoxWires(edges);
std::vector<AMCAX::TopoShape> faces = BuildBoxFaces(wires);
//Make a shell and add all faces in the shell
builder.MakeShell(shell);
for (const auto& face : faces)
{
builder.Add(shell, face);
}
AMCAX_API void MakeShell(TopoShell &s) const
Make an empty shell.
Class of shell.
Definition TopoShell.hpp:12