AnyCAD应用实例:
1 visual studio2022 下的anycad控件安装
对于想要试一试自制三维软件的朋友,anycad可能是一个不错的选择,因为它免费。
安装它也很简单,在visual studio 2022中新建一个vb.net项目,然后在nuget包管理中搜索“anycad”即可:
如上图,安装.net后缀的插件即可,安装完成后,可在项目的引用中查看:
表示anycad的控件安装成功,可以开始调用了。
2 调用anycad及简单示例:
anycad的官网提供了示例程序代码,不过都是用C#写的,C#.net和VB.net毕竟还是有不小的区别的,所以,本文中将会以VB.net的格式来重写:
1 导入命名空间:
在vb.net项目的主窗口代码中,导入命名空间
Imports AnyCAD.Foundation
Imports AnyCAD.Forms
2 初始化:
anycad的调用需要进行初始化,官网的C#程序是这样的:
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
// 初始化
AnyCAD.Foundation.GlobalInstance.Initialize();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
AnyCAD.Foundation.GlobalInstance.Destroy();
}
}
在vb.net中,我们这样改写一下:
初始化:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
AnyCAD.Foundation.GlobalInstance.Initialize()
End Sub
释放资源:
Private Sub Form1_FormClosed(sender As Object, e As FormClosedEventArgs) Handles Me.FormClosed
AnyCAD.Foundation.GlobalInstance.Destroy()
End Sub
3 控件显示:
官网的示例中,控件显示的容器选择的是splitcontainer:
public partial class MainForm : Form
{
RenderControl mRenderView;
public MainForm()
{
InitializeComponent();
mRenderView = new RenderControl(this.splitContainer1.Panel2);
// 这里不能调用AnyCAD其他的API
}
...
}
但实际上,不一定非要用splitcontainer,也可以用其他控件,比如picturebox控件:
mrenderview = New RenderControl(Picturebox2)
以上,一个anycad的三维控件初始化已经完成,如果这时候你点击调试启动按钮,在你的.net窗口上,会显示这样的画面:

如上图picturebox控件框内显示的蓝色背景的视图,即是anycad的三维空间。这时候,你可以添加代码去绘制三维空间的任何图形,如点、线、面、球体、圆柱、立方体、多面体等。
1 绘制三维体:
Dim shape1= ShapeBuilder.MakeCylinder(New GAx2(New GPnt(-10, 30, 0), GP.DX), 15.0, 10.0, 0.0)
Dim nd = BrepSceneNode.Create(shape1, Nothing, Nothing)
mrenderview.ShowSceneNode(nd)
shapebuilder是一个API函数,包含了常见的三维立体对象的创建方法,包括球体、长方体、圆柱体、圆锥、管子等。
类似的,创建球体:
shape1 = ShapeBuilder.MakeSphere(New GPnt(10, 0, 0), 5.0)
立方体:
shape1 = ShapeBuilder.MakeBox(New GAx2(New GPnt(30, 0, 0), GP.DZ), 5.0, 5.0, 5.0)
等等。
创建一个三维图形,算是最简单的使用了,anycad提供了多种图形创建和显示的函数,如SketchBuilder,包含了常见的三维平面基本体对象创建方法,包括点、直线段、圆弧曲线、长方形、多边形、BSpline等。
也可以直接导入一个绘制好的三维图形(支持step、igs等格式):
官网示例(C#):
private void stepToolStripMenuItem1_Click(object sender, EventArgs e)
{
OpenFileDialog dialog = new OpenFileDialog();
dialog.Filter = "STEP (*.stp;*.step)|*.stp;*.step";
if (dialog.ShowDialog() != DialogResult.OK)
return;
var shape = ShapeIO.Open(dialog.FileName);
if (shape == null)
return;
mRenderView.ShowShape(shape, Vector3.LightGray); // 用灰白色来显示模型
mRenderView.ZoomAll(); // 把模型缩放到合适位置
}
利用openfiledialog控件获取文件名,然后利用anycad的shapeio读取文件信息,并显示。这个代码比较简单,改成vb.net也很容易,这里就不写vb.net了。
anycad也提供了stepio、igesio来快速读取模型,但总的来说,三维模型的加载都是比较慢的,尤其是模型越大,加载越慢。
stepio:
OpenFileDialog dialog = new OpenFileDialog();
dialog.Filter = "STEP (*.stp;*.step)|*.stp;*.step";
if (dialog.ShowDialog() != DialogResult.OK)
return;
var shape = StepIO.Open(dialog.FileName);
if (shape == null)
return;
mRenderView.ShowShape(shape, new Vector3(0.8f)); // 显示指定个灰白色
igesio:
OpenFileDialog dialog = new OpenFileDialog();
dialog.Filter = "IGES (*.igs;*.iges)|*.igs;*.iges";
if (dialog.ShowDialog() != DialogResult.OK)
return;
var shape = IgesIO.Open(dialog.FileName);
if (shape == null)
return;
// 转换成BREP格式
BrepIO.Save(shape, dialog.FileName + ".brep");
4 三维动画:
当你创建了的三维图形或者导入了已经画好的图形结构,你可能有让图形动起来的需求,此时就涉及到如何让三维空间的图形执行动作,anycad提供的动作反馈函数AnimationCallback,用以执行动作。
所谓动画,其实就是对三维图形执行平移、旋转和缩放等矩阵变换放来模拟物体的运动,至于矩阵如何变换或者更深入的数学研究,此处不深入探讨(主要是不懂),作为使用者,只需要知道怎么调用平移、旋转及缩放等函数功能即可。
1 动画设置:
anycad提供了C#下的示例:
mRenderControl.SetAnimationCallback((float timer)=>{
// 更新构件
var matrixR = Matrix4.makeRotationAxis(new Vector3(0, 0, 1), time);
var matrixT = Matrix4.makeTranslation(-50, 0, 0);
ConeNode1.SetTransform(matrixR * matrixT);
ConeNode1.RequstUpdate();
// 更新场景
mRenderControl.RequestDraw();
});
但在vb.net下,代码需要转换,如果按照C#一样写,是不行的。
Dim cb3 As RenderControl.AnimationHandler
cb3 = New RenderControl.AnimationHandler(AddressOf ani)
mrenderview.SetAnimationCallback(cb3)
Public Sub ani(time As Single)
'这里添加图形动画代码,即平移、旋转、缩放或者三者组合
Dim matt1 As Matrix4 = Matrix4.makeTranslation(-50 * stp, 0, 0)
Dim matr1 As Matrix4 = Matrix4.makeRotationAxis(New Vector3(0, 0, 1), t)
Dim sn1 = scene1.FindNode(nodeid_list(0))
sn1.SetTransform(matt1) '先平移
sn1.SetTransform(matr1) '再旋转
sn1.RequstUpdate() '请求更新
mrenderview.RequestDraw(EnumUpdateFlags.Scene) '控件刷新
End Sub
上面关于动画反馈函数的代码,仅是一个简单的示例,大家可以根据自己的需要,将所有关于图形移动的代码全部写在这个函数里,函数会不停的刷新(time是时间,设置动画反馈后,时间就会开始计时,可以停止)。
这个反馈函数只需要设置一次即可,如果想要停止动画,只需要将调用设置为null即可,VB.net中为Nothing。
mrenderview.SetAnimationCallback(Nothing)
再次启用,只需要再设置一次即可。
mrenderview.SetAnimationCallback(cb3)
2 获取三维体的UUID(场景遍历)
uuid是三维空间的每一个实体(圆柱、直线、复合体等)的唯一标志,在每一次载入时,实体的uuid虽然会变化,但在当前空间场景内,uuid都是唯一的,因此可以通过获取实体的uuid,来对其进行单独操作,如获取其点、线、面参数等。
一般来说,在创建三维体或者导入三维体的时候,都可以及时获取其uuid,可以通过list来存储以备后面调用:
Dim shape = ShapeIO.Open(fl)
Dim node = BrepSceneNode.Create(shape, mMaterial, Nothing, 1)
node.SetSubShapePickable(False)
scene1.AddNode(node)
Dim nd_id = node.GetUuid()
nodeid_list.Add(nd_id)
但是,如果不知道三维空间中的实体的uuid怎么办呢?可以利用anycad的场景遍历函数,来获取所有实体对象(scenenode)。
官网示例是C#:
for(var itr = scene.CreateIterator();itr.More(); itr.Next())
{
var node = itr.Current();
//....
}
转换成vb.net代码,如下:
Dim scene1 as SceneNode
Dim snin As SceneNodeIterator = scene1.CreateIterator()
While snin.More '场景循环遍历
Dim nd1 As SceneNode = snin.Current()
Dim nduuid = nd1.GetUuid()
ListBox2.Items.Add(nduuid)
snin.Next()
End While
官网API的解释:
more用于判断是否还有scenenode的标志,next是用于进入下一个scenenode,current是获取当前scenenode对象。
此外,三维空间还有很多其他参数,如材质,如三维体之间的融合方式(相交、相差、相并):
计算三维体的距离,进行曲面分析,计算点云等等,所有三维软件的功能,都可以自己用代码实现,只是需要花更多时间去研究,本文只是一个初步的介绍,能够帮你实现一个基本的三维图形显示和动画功能,如果你正好只需要简单应用,那么就可以了。如果要高级的功能,可以去官网看手册。
anycad资料:
[1]: http://www.anycad.cn/guide/
[2]: http://anycad.cn/api/