概述
本教程提供了使用 T 网格样条进行建模的基本用法,与细分建模类似,建模方式同样是从创建一个基本体开始,通过拉伸,变换,细分等生成最终曲面。
构建基本体
模块支持构建多种基本体,构建一个边长为3,每方向分割2段的立方体代码如下。
T 网格样条结构的类。 当前版本未导出底层的接口功能
定义 TMSpline.hpp:30
T 网格样条接口中用于创建立方体的类
定义 TMSplineMakeCube.hpp:15
FrameT< double, 3 > Frame3
三维标架
定义 FrameT.hpp:885
构建一个底面半径为4,上面半径为2,高为4的圆台可以使用圆锥的提供的函数,默认沿着旋转方向分割8段,沿着高的方向分割4段。
T 网格样条接口中用于创建圆锥体的类
定义 TMSplineMakeCone.hpp:16
构建一个漩涡模型
模型预览
本教程使用简单的漩涡模型展示细分建模模块中的一些主要建模功能。模型如下图所示:
漩涡模型
命名空间
为了示例代码清晰,使用命名空间
AMCAX TMSpline 模块提供的所有接口所在的命名空间。
定义 misc.docu:70
AMCAX 内核提供的所有接口所在的命名空间。
定义 misc.docu:8
构建底面
从构建一个平面开始。
TMSplineMakeRectangle mkRect(frame, 3, 3, 3, 3);
TMSpline* tsp = mkRect.BuildSpline();
点击这里example1可获得以上示例完整源码,大家根据学习需要自行下载。
拉伸面和变换
拉伸中间的面形成一个峰,注意执行拉伸函数仅修改网格拓扑,没有移动任何元素的位置。
TMSplineExtrude extrude;
std::vector<int> face_id = {4};
std::vector<int> face_id_new;
if (extrude.CanExtrudeFaces(tsp, face_id))
{
extrude.ExtrudeFaces(tsp, face_id, face_id_new);
}
施加平移和旋转的变换将新生成的面移动到指定位置。 不同与细分建模,在变换后必须要执行一个后处理函数。
TMSplineTransform trsfF;
trsfF.SetTransformation(trsfMove);
trsfF.TransformTMSplineFaces(tsp, face_id_new);
trsfF.SetTransformation(trsfRot);
trsfF.TransformTMSplineFaces(tsp, face_id_new);
trsfF.TransformReprocessing(tsp);
constexpr const CoordType & Coord() const noexcept
获取方向的内在坐标
定义 DirectionT.hpp:213
constexpr const DirectionT< Scalar, DIM > & Direction() const noexcept
获取三维主方向(z 方向)
定义 FrameT.hpp:441
constexpr double pi
数学常数 Pi,圆的周长与直径之比
定义 Constants.hpp:42
AxisT< double, 3 > Axis3
三维轴
定义 AxisT.hpp:423
TransformationT< double, 3 > Transformation3
三维变换
定义 TransformationT.hpp:1102
VectorT< double, 3 > Vector3
三维向量
定义 VectorT.hpp:707
DirectionT< double, 3 > Direction3
三维方向
定义 DirectionT.hpp:587
PointT< double, 3 > Point3
三维点
定义 PointT.hpp:459
点击这里example2可获得以上示例完整源码,大家根据学习需要自行下载。
删除顶面
TMSplineReduce 提供删除面等一系列简化网格的工具,其中 remove 方法不会留下洞。
TMSplineReduce reduce;
reduce.DeleteFaces(tsp, face_id_new);
点击这里example3可获得以上示例完整源码,大家根据学习需要自行下载。
拉伸边和变换
将删除面留下的边向四周拉伸从而生成新的顶面,先执行拉伸操作,然后施加缩放变换将新生成的边移动到指定位置。
std::vector<int> edgeid;
std::vector<int> edge_id_new;
for (int i = 0; i < tsp->numEdges(); ++i)
{
if (TMSplineCheck::IsEdgeBoundary(tsp, i))
{
int v0, v1;
TMSplineTool::EdgeVertexIndexs(tsp, i, v0, v1);
Point3 pv0 = TMSplineTool::ControlPosition(tsp, v0);
Point3 pv1 = TMSplineTool::ControlPosition(tsp, v1);
if (pv0.
Z() > 0.9 * h && pv1.
Z() > 0.9 * h)
{
edgeid.push_back(i);
}
}
}
extrude.CanExtrudeEdges(tsp, edgeid);
extrude.ExtrudeEdges(tsp, edgeid, edge_id_new);
TMSplineTransform trsfE;
trsfE.SetTransformation(trsfScale);
trsfE.TransformTMSplineEdges(tsp, edge_id_new);
trsfE.TransformReprocessing(tsp);
constexpr const Scalar & Z() const noexcept
获取点的 z 坐标,仅在 DIM >= 3 时可用
定义 PointT.hpp:136
点击这里example4可获得以上示例完整源码,大家根据学习需要自行下载。
执行加厚操作
将形状进行加厚,从而创建一个实体。
TMSplineThicken mkThick;
mkThick.ThickenTMSpline(tsp, 0.2);
点击这里example5可获得以上示例完整源码,大家根据学习需要自行下载。
设置尖锐特征
T 网格样条允许选择一些边设置为尖锐特征,此时曲面在该边表现为一个折痕。
std::vector<int> edgeidC;
for (int i = 0; i < tsp->numEdges(); ++i)
{
int v0, v1;
TMSplineTool::EdgeVertexIndexs(tsp, i, v0, v1);
Point3 pv0 = TMSplineTool::ControlPosition(tsp, v0);
Point3 pv1 = TMSplineTool::ControlPosition(tsp, v1);
if (pv0.
Z() < 0.1 && pv1.
Z() < 0.1)
{
edgeidC.push_back(i);
}
}
TMSplineCreaseTool crease;
crease.AddCreaseEdge(tsp, edgeidC);
点击这里example6可获得以上示例完整源码,大家根据学习需要自行下载。
执行细分
对 T 网格样条的所有面执行 1-4 细分,类似细分建模,同样支持选择边并将与该边拓扑平行的所有面一分为二。
TMSplineSplit split;
face_id.resize(tsp->numFaces());
for (int i = 0; i < face_id.size(); ++i)
{
face_id[i] = i;
}
split.SplitFacesCross(tsp, face_id);
网格化
对结果曲面进行网格化,网格化参数越大,逼近程度越高
TMSplineMeshing tspMesh(tsp, 4);
tspMesh.UpdateDrawMesh();
导出为网格
该模块提供给将网格化结果导出为 OBJ 文件格式,此外,还支持将控制网导出为 OBJ 格式进行网格细分。
TMSplineMeshingIO meshIO;
std::string fileNameOBJ = "sampleResult.obj";
meshIO.ExportToOBJ(fileNameOBJ, tspMesh.GetDrawMesh());
点击这里example7可获得 T 网格样条建模示例完整源码,大家根据学习需要自行下载。
附录
下面列出了此示例的完整代码:
void MakeTornado()
{
double h = 2;
TMSplineMakeRectangle mkRect(frame, 3, 3, 3, 3);
TMSpline* tsp = mkRect.BuildSpline();
TMSplineExtrude extrude;
std::vector<int> face_id = {4};
std::vector<int> face_id_new;
if (extrude.CanExtrudeFaces(tsp, face_id))
{
extrude.ExtrudeFaces(tsp, face_id, face_id_new);
}
TMSplineTransform trsfF;
trsfF.SetTransformation(trsfMove);
trsfF.TransformTMSplineFaces(tsp, face_id_new);
trsfF.SetTransformation(trsfRot);
trsfF.TransformTMSplineFaces(tsp, face_id_new);
trsfF.TransformReprocessing(tsp);
TMSplineReduce reduce;
reduce.DeleteFaces(tsp, face_id_new);
std::vector<int> edgeid;
std::vector<int> edge_id_new;
for (int i = 0; i < tsp->numEdges(); ++i)
{
if (TMSplineCheck::IsEdgeBoundary(tsp, i))
{
int v0, v1;
TMSplineTool::EdgeVertexIndexs(tsp, i, v0, v1);
Point3 pv0 = TMSplineTool::ControlPosition(tsp, v0);
Point3 pv1 = TMSplineTool::ControlPosition(tsp, v1);
if (pv0.
Z() > 0.9 * h && pv1.
Z() > 0.9 * h)
{
edgeid.push_back(i);
}
}
}
extrude.CanExtrudeEdges(tsp, edgeid);
extrude.ExtrudeEdges(tsp, edgeid, edge_id_new);
TMSplineTransform trsfE;
trsfE.SetTransformation(trsfScale);
trsfE.TransformTMSplineEdges(tsp, edge_id_new);
trsfE.TransformReprocessing(tsp);
TMSplineThicken mkThick;
mkThick.ThickenTMSpline(tsp, 0.2);
std::vector<int> edgeidC;
for (int i = 0; i < tsp->numEdges(); ++i)
{
int v0, v1;
TMSplineTool::EdgeVertexIndexs(tsp, i, v0, v1);
Point3 pv0 = TMSplineTool::ControlPosition(tsp, v0);
Point3 pv1 = TMSplineTool::ControlPosition(tsp, v1);
if (pv0.
Z() < 0.1 && pv1.
Z() < 0.1)
{
edgeidC.push_back(i);
}
}
TMSplineCreaseTool crease;
crease.AddCreaseEdge(tsp, edgeidC);
TMSplineSplit split;
face_id.resize(tsp->numFaces());
for (int i = 0; i < face_id.size(); ++i)
{
face_id[i] = i;
}
split.SplitFacesCross(tsp, face_id);
TMSplineMeshing tspMesh(tsp, 4);
tspMesh.UpdateDrawMesh();
TMSplineMeshingIO meshIO;
std::string fileNameOBJ = "sampleResult.obj";
meshIO.ExportToOBJ(fileNameOBJ, tspMesh.GetDrawMesh());
delete tsp;
}
用于将 T 网格样条中的三角网格导出为 STL 或 OBJ 格式的类