AMCAX Kernel
Geometry kernel for CAD/CAE/CAM
AMCAX Kernel 1.0.0.0
Loading...
Searching...
No Matches
A PolyMesh Modeling Sample

Overview

This tutorial provides the basic usage of using polygonal meshes for subdivision surface modeling. Subdivision modeling generally starts with creating a primitive and generates a dense mesh approximation of a surface through stretching, transformation, subdivision, etc.

Construction of primitive shapes

The module supports the construction of various primitive geometries, for example, makeing a cube with a side length of 3 and dividing 2 segments in each direction. The code is as follows.

AMCAX::SubD::MeshMakeCube makeCube(frame, 3, 3, 3, 2, 2, 2);
AMCAX::SubD::PolyMesh* mesh = makeCube.BuildMesh();
Class of PolyMesh API for make a cube.
Definition MeshMakeCube.hpp:15
Class of TMSpline structure The Low Level API functions are not exported for this version.
Definition PolyMesh.hpp:23
FrameT< double, 3 > Frame3
3D frame
Definition FrameT.hpp:885

You can also use the MeshMakeCone to construct a frustum with a base radius of 4, an upper radius of 2, and a height of 4. By default, it is divided into 8 segments along the rotation direction and 4 segments along the height direction

AMCAX::SubD::MeshMakeCone makeCone(frame, 4, 2, 4);
AMCAX::SubD::PolyMesh* mesh = makeCone.BuildMesh();
Class of PolyMesh API for make a cone.
Definition MeshMakeCone.hpp:15

Build a vortex model

Model Preview

This tutorial uses a simple vortex model to show some of the main modeling functions in the polymesh subdivision modeling module The model is shown in the figure below:

The vortex model

Using namespace

using namespace AMCAX;
using namespace SubD;
Namespace of all interface in the AMCAX SubD module.
Definition misc.docu:63
Namespace of all interface in the AMCAX kernel.
Definition misc.docu:8

Build Bottom mesh

Start by constructing a plane.

Frame3 frame;
MeshMakeRectangle mkRect(frame, 3, 3, 3, 3);
PolyMesh* mesh = mkRect.BuildMesh();

Click here example1 to get the complete source code for the above example, which you can download according to your learning needs.

Extrude faces and apply transformations

Extrude the middle face to form a peak. Only change the topology, the new result is coincide the old result, and use MeshTransform to move the new result

std::vector<int> face_id = {4};
std::vector<int> face_id_new;
MeshExtrude::ExtrudeFace(mesh, face_id, face_id_new);

Apply translation and rotation transformations to the newly generated faces

Vector3 vh(frame.Direction().Coord() * h);
MeshTransform trsfF;
Transformation3 trsfMove;
trsfMove.SetTranslation(vh);
trsfF.SetTransformation(trsfMove);
trsfF.TransformMeshFaces(mesh, face_id_new);
trsfRot.SetRotation(Axis3(Point3(1.5, 1.5, 0.), Direction3(0., 0., 1.)), M_PI / 4);
trsfF.SetTransformation(trsfRot);
trsfF.TransformMeshFaces(mesh, face_id_new);
constexpr const CoordType & Coord() const noexcept
Get the intrinsic coordinate of the direction.
Definition DirectionT.hpp:213
constexpr const DirectionT< Scalar, DIM > & Direction() const noexcept
Get the main direction (z direction) in 3D.
Definition FrameT.hpp:441
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 void SetTranslation(const VectorT< OtherScalar, DIM > &vec) noexcept
Set the transformation as the translation.
Definition TransformationT.hpp:311
AxisT< double, 3 > Axis3
3D axis
Definition AxisT.hpp:423
TransformationT< double, 3 > Transformation3
3D transformation
Definition TransformationT.hpp:1102
VectorT< double, 3 > Vector3
3D vector
Definition VectorT.hpp:707
DirectionT< double, 3 > Direction3
3D direction
Definition DirectionT.hpp:587
PointT< double, 3 > Point3
3D point
Definition PointT.hpp:459

Click here example2 to get the complete source code for the above example, which you can download according to your learning needs.

Delete top face

Can freely delete any number of faces and leave holes

MeshReduce::DeleteFaces(mesh, face_id_new);

Click here example3 to get the complete source code for the above example, which you can download according to your learning needs.

Extrude edges and apply transformations

Extrude the edges left by the deleted face towards all sides to construct a new top faces.

std::vector<int> edgeid;
std::vector<int> edge_id_new;
for (int i = 0; i < mesh->numEdges(); ++i)
{
if (MeshCheck::IsEdgeBoundary(mesh, i))
{
int v0, v1;
MeshTool::EdgeVertexIndexs(mesh, i, v0, v1);
Point3 pv0 = MeshTool::Position(mesh, v0);
Point3 pv1 = MeshTool::Position(mesh, v1);
if (pv0.Z() > 0.9 * h && pv1.Z() > 0.9 * h)
{
edgeid.push_back(i);
}
}
}
MeshExtrude::ExtrudeEdge(mesh, edgeid, edge_id_new);
MeshTransform trsfE;
Transformation3 trsfScale;
trsfScale.SetScale(Point3(1.5, 1.5, h), 3);
trsfE.SetTransformation(trsfScale);
trsfE.TransformMeshEdges(mesh, edge_id_new);
constexpr const Scalar & Z() const noexcept
Get z-coordinate of a point, only available when DIM >= 3.
Definition PointT.hpp:136
void SetScale(const PointT< OtherScalar, DIM > &point, const OtherScalar2 &s)
Set the transformation as the scaling from a point.
Definition TransformationT.hpp:224

Click here example4 to get the complete source code for the above example, which you can download according to your learning needs.

Perform thickening

Thicken the shape to construct a solid.

MeshOffset::ThickenMesh(mesh, 0.2);

Click here example5 to get the complete source code for the above example, which you can download according to your learning needs.

Apply face split

Split the faces that connect the upper and lower parts with significant changes makes the results smoother. By split loop an edge, all faces that are topologically parallel to that edge are split in half.

for (int i = 0; i < mesh->numEdges(); ++i)
{
int v0, v1;
MeshTool::EdgeVertexIndexs(mesh, i, v0, v1);
Point3 pv0 = MeshTool::Position(mesh, v0);
Point3 pv1 = MeshTool::Position(mesh, v1);
if (std::fabs(pv1.Z() - pv0.Z()) > 0.8 * h)
{
MeshSplit::SplitLoop(mesh, i);
i = 0;
}
}

Click here example6 to get the complete source code for the above example, which you can download according to your learning needs.

Set crease edge features

You can select some edges to set the sharpness level, which is between 0 and 1. The larger the value, the sharper the final shape will be at the edge. When the value is greater than 1, the final result will show sharp feature edges

std::vector<int> edgeidCrese;
for (int i = 0; i < mesh->numEdges(); ++i)
{
int v0, v1;
MeshTool::EdgeVertexIndexs(mesh, i, v0, v1);
Point3 pv0 = MeshTool::Position(mesh, v0);
Point3 pv1 = MeshTool::Position(mesh, v1);
if (pv0.Z() < 0.1 && pv1.Z() < 0.1 && pv0.Distance(Point3(1.5, 1.5, 0.)) > 1 && pv1.Distance(Point3(1.5, 1.5, 0.)) > 1)
{
edgeidCrese.push_back(i);
}
}
std::vector<double> creaseLevel(edgeidCrese.size(), 1.0);
MeshCreaseTool::AddCreaseEdge(mesh, edgeidCrese, creaseLevel);
auto Distance(const PointT< OtherScalar, DIM > &other) const noexcept
Compute the Euclidean distance from the other point.
Definition PointT.hpp:180

Do Subdivision

This module provides two subdivision methods, the Catmull-Clark subdivision supports arbitrary meshes, the Loop subdivision only supports triangular meshes. The subdivided shape can still be edited again.

MeshSubdivideHE::CatmullClark(mesh, 3);

Save Mesh

This module provides the option to save result as OBJ files and OFF files

std::string fileNameOBJ = "sampleResult.obj";
PolyMeshIO::WriteMesh(fileNameOBJ, mesh);

Click here example7 to obtain the complete source code of the polygonal mesh subdivision modeling example, you can download it according to your learning needs.

Appendix

The complete code of this sample is listed here:

#include <common/AxisT.hpp>
void MakeTornado()
{
double h = 2;
Frame3 frame;
MeshMakeRectangle mkRect(frame, 3, 3, 3, 3);
PolyMesh* mesh = mkRect.BuildMesh();
std::vector<int> face_id = {4};
std::vector<int> face_id_new;
MeshExtrude::ExtrudeFace(mesh, face_id, face_id_new);
Vector3 vh(frame.Direction().Coord() * h);
MeshTransform trsfF;
Transformation3 trsfMove;
trsfMove.SetTranslation(vh);
trsfF.SetTransformation(trsfMove);
trsfF.TransformMeshFaces(mesh, face_id_new);
Transformation3 trsfRot;
trsfRot.SetRotation(Axis3(Point3(1.5, 1.5, 0.), Direction3(0., 0., 1.)), M_PI / 4);
trsfF.SetTransformation(trsfRot);
trsfF.TransformMeshFaces(mesh, face_id_new);
MeshReduce::DeleteFaces(mesh, face_id_new);
std::vector<int> edgeid;
std::vector<int> edge_id_new;
for (int i = 0; i < mesh->numEdges(); ++i)
{
if (MeshCheck::IsEdgeBoundary(mesh, i))
{
int v0, v1;
MeshTool::EdgeVertexIndexs(mesh, i, v0, v1);
Point3 pv0 = MeshTool::Position(mesh, v0);
Point3 pv1 = MeshTool::Position(mesh, v1);
if (pv0.Z() > 0.9 * h && pv1.Z() > 0.9 * h)
{
edgeid.push_back(i);
}
}
}
MeshExtrude::ExtrudeEdge(mesh, edgeid, edge_id_new);
MeshTransform trsfE;
Transformation3 trsfScale;
trsfScale.SetScale(Point3(1.5, 1.5, h), 3);
trsfE.SetTransformation(trsfScale);
trsfE.TransformMeshEdges(mesh, edge_id_new);
MeshOffset::ThickenMesh(mesh, 0.2);
for (int i = 0; i < mesh->numEdges(); ++i)
{
int v0, v1;
MeshTool::EdgeVertexIndexs(mesh, i, v0, v1);
Point3 pv0 = MeshTool::Position(mesh, v0);
Point3 pv1 = MeshTool::Position(mesh, v1);
if (std::fabs(pv1.Z() - pv0.Z()) > 0.8 * h)
{
MeshSplit::SplitLoop(mesh, i);
i = 0;
}
}
std::vector<int> edgeidCrese;
for (int i = 0; i < mesh->numEdges(); ++i)
{
int v0, v1;
MeshTool::EdgeVertexIndexs(mesh, i, v0, v1);
Point3 pv0 = MeshTool::Position(mesh, v0);
Point3 pv1 = MeshTool::Position(mesh, v1);
if (pv0.Z() < 0.1 && pv1.Z() < 0.1 && pv0.Distance(Point3(1.5, 1.5, 0.)) > 1 && pv1.Distance(Point3(1.5, 1.5, 0.)) > 1)
{
edgeidCrese.push_back(i);
}
}
std::vector<double> creaseLevel(edgeidCrese.size(), 1.0);
MeshCreaseTool::AddCreaseEdge(mesh, edgeidCrese, creaseLevel);
MeshSubdivideHE::CatmullClark(mesh, 3);
std::string fileNameOBJ = "sampleResult.obj";
PolyMeshIO::WriteMesh(fileNameOBJ, mesh);
delete mesh;
}
Class of axis.
Class of frame.
Class of PolyMesh check Tool.
Class of PolyMesh API for make crease edge.
Class of PolyMesh API for extrude method.
Class of PolyMesh API for make a plane rectangle.
Class of PolyMesh API for Thicken a Mesh.
Class of PolyMesh API for Reduce a Mesh.
Class of PolyMesh API for split mesh.
Class of PolyMesh API for mesh subdividion, which will use half-edge data structure to modify the mes...
Class of PolyMesh Tool.
Class of transforming a PolyMesh.
Class of PolyMesh API for load and write a polymesh.
Class of vector.