明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 4629|回复: 10

ARX的COM函数库之实体篇(acdbEntMake)

  [复制链接]
发表于 2013-11-15 16:17:07 | 显示全部楼层 |阅读模式
本帖最后由 efan2000 于 2014-7-27 19:35 编辑

通过封装ARX的函数,使之能够在VB、VBA或者.NET等中以COM方式访问。
acdbEntMake对应的COM函数为:Function AcdbEntMake(codetype, codevalue) As Long,其中codetype为整型的数组,codevalue为变体的数组,根据组码来确定类型。
  1. ' 创建圆弧
  2. Sub testAcdbEntMakeArc()
  3.     Dim ct(0 To 4) As Integer
  4.     Dim cv(0 To 4) As Variant
  5.     ct(0) = 0
  6.     cv(0) = "ARC"
  7.     Dim pt1(0 To 2) As Double
  8.     ct(1) = 10 ' 圆心
  9.     cv(1) = pt1
  10.     ct(2) = 40 ' 半径
  11.     cv(2) = 1
  12.     ct(3) = 50 ' 起点角度
  13.     cv(3) = 0
  14.     ct(4) = 51 ' 端点角度
  15.     cv(4) = 45
  16.   Debug.Print AcdbEntMake(ct, cv)
  17. End Sub

  18. ' 创建圆弧-新版
  19. Sub testAcdbEntMakeArc()
  20.     Dim ent As ResultBuffer
  21.     Set ent = New ResultBuffer
  22.     ent.AddTypedValue 0, "ARC"
  23.     Dim pt(0 To 2) As Double
  24.     ent.AddTypedValue 10, pt ' 圆心
  25.     ent.AddTypedValue 40, 1 ' 半径
  26.     ent.AddTypedValue 50, 0 ' 起点角度
  27.     ent.AddTypedValue 51, 45 ' 端点角度
  28.     Debug.Print AcdbEntMake(ent)
  29. End Sub

  1. ' 创建圆
  2. Sub testAcdbEntMakeCircle()
  3.     Dim ct(0 To 2) As Integer
  4.     Dim cv(0 To 2) As Variant
  5.     ct(0) = 0
  6.     cv(0) = "CIRCLE"
  7.     Dim pt1(0 To 2) As Double
  8.     ct(1) = 10 ' 圆心
  9.     cv(1) = pt1
  10.     ct(2) = 40 ' 半径
  11.     cv(2) = 3.5
  12.     Debug.Print AcdbEntMake(ct, cv)
  13. End Sub

  14. ' 创建圆-新版
  15. Sub testAcdbEntMakeCircle()
  16.     Dim ent As ResultBuffer
  17.     Set ent = New ResultBuffer
  18.     ent.AddTypedValue 0, "CIRCLE"
  19.     Dim pt1(0 To 2) As Double
  20.     ent.AddTypedValue 10, pt1 ' 圆心
  21.     ent.AddTypedValue 40, 3.5 ' 半径
  22.     Debug.Print AcdbEntMake(ent)
  23. End Sub

  1. '插入块
  2. Sub testAcdbEntMakeInsert()
  3.     Dim ct(0 To 2) As Integer
  4.     Dim cv(0 To 2) As Variant
  5.     ct(0) = 0
  6.     cv(0) = "INSERT"
  7.     ct(1) = 2 ' 名称
  8.     cv(1) = "Block"
  9.     Dim pt(0 To 2) As Double
  10.     ct(2) = 10 ' 位置
  11.     cv(2) = pt
  12.    Debug.Print AcdbEntMake(ct, cv)
  13. End Sub

  1. ' 创建直线
  2. Sub testAcdbEntMakeLine()
  3.     Dim ct(0 To 2) As Integer
  4.     Dim cv(0 To 2) As Variant
  5.     ct(0) = 0
  6.     cv(0) = "LINE"
  7.     Dim pt1(0 To 2) As Double
  8.     ct(1) = 10 ' 起点
  9.     cv(1) = pt1
  10.     Dim pt2(0 To 2) As Double
  11.     pt2(0) = 10
  12.     ct(2) = 11 ' 端点
  13.     cv(2) = pt2
  14.     Debug.Print AcdbEntMake(ct, cv)
  15. End Sub

  1. ' 创建多行文字
  2. Sub testAcdbEntMakeMText()
  3.     Dim ct(0 To 4) As Integer
  4.     Dim cv(0 To 4) As Variant
  5.     ct(0) = 0
  6.     cv(0) = "MTEXT"
  7.     ct(1) = 100
  8.     cv(1) = "AcDbEntity"
  9.     ct(2) = 100
  10.     cv(2) = "AcDbMText"
  11.     Dim pt(0 To 2) As Double
  12.     ct(3) = 10 ' 位置
  13.     cv(3) = pt
  14.     ct(4) = 1 ' 内容
  15.     cv(4) = "MText"
  16.     Debug.Print AcdbEntMake(ct, cv)
  17. End Sub

  1. ' 创建点
  2. Sub testAcdbEntMakePoint()
  3.     Dim ct(0 To 1) As Integer
  4.     Dim cv(0 To 1) As Variant
  5.     ct(0) = 0
  6.     cv(0) = "POINT"
  7.     Dim pt1(0 To 2) As Double
  8.     ct(1) = 10 ' 位置
  9.     cv(1) = pt1
  10.     Debug.Print AcdbEntMake(ct, cv)
  11. End Sub

  1. ' 创建多段线
  2. Sub testAcdbEntMakePolyline()
  3.     Dim ct(0 To 5) As Integer
  4.     Dim cv(0 To 5) As Variant
  5.     ct(0) = 0
  6.     cv(0) = "LWPOLYLINE"
  7.     ct(1) = 100
  8.     cv(1) = "AcDbEntity"
  9.     ct(2) = 100
  10.     cv(2) = "AcDbPolyline"
  11.     ct(3) = 90 ' 顶点数
  12.     cv(3) = 2
  13.     Dim pt1(0 To 1) As Double
  14.     ct(4) = 10 ' 顶点
  15.     cv(4) = pt1
  16.     Dim pt2(0 To 1) As Double
  17.     pt2(0) = 10
  18.     ct(5) = 10 ' 顶点
  19.     cv(5) = pt2
  20.     Debug.Print AcdbEntMake(ct, cv)
  21. End Sub

  1. ' 创建文字
  2. Sub testAcdbEntMakeText()
  3.     Dim ct(0 To 3) As Integer
  4.     Dim cv(0 To 3) As Variant
  5.     ct(0) = 0
  6.     cv(0) = "TEXT"
  7.     Dim pt1(0 To 2) As Double
  8.     ct(1) = 10 ' 位置
  9.     cv(1) = pt1
  10.     ct(2) = 40 ' 高度
  11.     cv(2) = 2
  12.     ct(3) = 1 ' 内容
  13.     cv(3) = "Text"
  14.     Debug.Print AcdbEntMake(ct, cv)
  15. End Sub


2014.07.25
修正AcedGrRead的BUG。
2014.06.19
原来版本部分函数已更改,新增ResultBuffer和TypedValue类处理ARX的resbuf结构。
支持R2004-R2014版本的AutoCAD32位版本。

注:函数库在R2007测试通过,理论上在R2008、R2009的32版本可以通用,其它版本的将于后续发布。
增加了R2010的32位版本mccomarx18,R2011、R2012的可以通用,但没测试。
增加了R2004的32位版本mccomarx16,R2005、R2006的可以通用,但没测试。







本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x
 楼主| 发表于 2013-11-15 16:42:44 | 显示全部楼层
本帖最后由 efan2000 于 2013-12-3 16:45 编辑

1000次创建圆的速度
  1. Sub test10000()
  2.     Dim t0 As Double    t0 = ThisDrawing.GetVariable("CDATE")
  3.     Dim i As Integer
  4.     For i = 1 To 10000
  5.         testAcdbEntMakeCircle
  6.     Next
  7.     Dim t1 As Double
  8.     t1 = ThisDrawing.GetVariable("CDATE")
  9.     Dim str As String
  10.     Debug.Print AcdbRToS((t1 - t0) * 1000000#, 2, 6, str)
  11.     Debug.Print "EntMakeCircle: " & str
  12.     t0 = ThisDrawing.GetVariable("CDATE")
  13.     For i = 1 To 10000
  14.         Dim c(0 To 2) As Double
  15.         ThisDrawing.ModelSpace.AddCircle c, 3.5
  16.     Next
  17.     t1 = ThisDrawing.GetVariable("CDATE")
  18.     Debug.Print AcdbRToS((t1 - t0) * 1000000#, 2, 6, str)
  19.     Debug.Print "AddCircle: " & str
  20. End Sub

  21. ' 创建圆
  22. Sub testAcdbEntMakeCircle()
  23.     Dim ct(0 To 2) As Integer
  24.     Dim cv(0 To 2) As Variant
  25.     ct(0) = 0
  26.     cv(0) = "CIRCLE"
  27.     Dim pt1(0 To 2) As Double
  28.     ct(1) = 10 ' 圆心
  29.     cv(1) = pt1
  30.     ct(2) = 40 ' 半径
  31.     cv(2) = 3.5
  32.     AcdbEntMake ct, cv
  33.     'Debug.Print AcdbEntMake(ct, cv)
  34. End Sub

输出:
5100
EntMakeCircle: 1.102686
5100
AddCircle: 2.693385
5100
EntMakeCircle: 1.199543
5100
AddCircle: 4.481524
5100
EntMakeCircle: 1.333654
5100
AddCircle: 6.210059
可以看出acdbEntMake创建圆的速度比传统的创建圆快。
发表于 2013-11-16 20:46:05 | 显示全部楼层
本帖最后由 yshf 于 2013-11-16 20:48 编辑

但还是比Lisp的entmake 慢
  1. (defun c:TT()
  2.     (setq t0 (getvar "cdate"))
  3.     (repeat 1000
  4.         (entmake (list '(0 . "circle")
  5.                        '(10  0 0 0 )
  6.                         '(40 . 3.5)
  7.                  )
  8.         )
  9.     )
  10.     (setq t1 (getvar "cdate")
  11.           dt (* 1e6 (- t1 t0))
  12.     )
  13.     (princ (strcat "\n共耗时:" (rtos dt 2 6)))
  14.     (princ)
  15. )
命令: TT
共耗时:0.111759

命令:
命令: TT
共耗时:0.108033

命令:
命令: TT
共耗时:0.122935
发表于 2013-11-16 20:53:31 | 显示全部楼层
生成10000个圆耗时测试,时间单位为秒:
命令: tt

共耗时:1.139939

命令:
命令: tt

共耗时:1.139939

命令:
命令: tt

共耗时:1.154840
发表于 2013-11-17 08:46:49 | 显示全部楼层
谢谢分享!好东西,下一个收藏。希望2010及以后版本的,我用的是AutoCAD 2010
 楼主| 发表于 2013-11-18 11:10:22 | 显示全部楼层
yshf 发表于 2013-11-16 20:53
生成10000个圆耗时测试,时间单位为秒:
命令: tt

可以搭个环境测试下,每个人的电脑配置、CAD版本都不同,测试结果会有偏差,只能做为参照。
 楼主| 发表于 2013-11-18 11:41:02 | 显示全部楼层
创建块的示例
  1. ' 创建块
  2. Sub testAcdbEntMakeBlock()
  3.     Dim ct(0 To 3) As Integer
  4.     Dim cv(0 To 3) As Variant
  5.     ct(0) = 0
  6.     cv(0) = "BLOCK"
  7.     ct(1) = 2 ' 名称
  8.     cv(1) = "Block"
  9.     Dim pt(0 To 2) As Double
  10.     ct(2) = 10 ' 基点
  11.     cv(2) = pt
  12.     ct(3) = 70 ' 标记
  13.     cv(3) = 0
  14.     Dim r As Integer
  15.     r = AcdbEntMake(ct, cv)
  16.     Debug.Print r
  17.     If r = 5100 Then
  18.         testAcdbEntMakeCircle
  19.         testAcdbEntMakeEndBlock
  20.     End If
  21. End Sub

  22. ' 创建圆
  23. Sub testAcdbEntMakeCircle()
  24.     Dim ct(0 To 2) As Integer
  25.     Dim cv(0 To 2) As Variant
  26.     ct(0) = 0
  27.     cv(0) = "CIRCLE"
  28.     Dim pt1(0 To 2) As Double
  29.     ct(1) = 10 ' 圆心
  30.     cv(1) = pt1
  31.     ct(2) = 40 ' 半径
  32.     cv(2) = 3.5
  33.     Debug.Print AcdbEntMake(ct, cv)
  34. End Sub

  35. ' 结束块
  36. Sub testAcdbEntMakeEndBlock()
  37.     Dim ct(0 To 0) As Integer
  38.     Dim cv(0 To 0) As Variant
  39.     ct(0) = 0
  40.     cv(0) = "ENDBLK"
  41.     Debug.Print AcdbEntMake(ct, cv)
  42.     ' 正常情况下,结果为RTKword = -5005
  43.     ' 通过AcedGetInput,获取块名称
  44.     Dim s As String
  45.     Debug.Print AcedGetInput(s)
  46.     Debug.Print s
  47. End Sub

  48. ' 创建匿名块
  49. Sub testAcdbEntMakeAnonymousBlock()
  50.     Dim ct(0 To 3) As Integer
  51.     Dim cv(0 To 3) As Variant
  52.     ct(0) = 0
  53.     cv(0) = "BLOCK"
  54.     ct(1) = 2 ' 匿名块名称
  55.     cv(1) = "*U"
  56.     Dim pt(0 To 2) As Double
  57.     ct(2) = 10 ' 基点
  58.     cv(2) = pt
  59.     ct(3) = 70 ' 匿名块标记
  60.     cv(3) = 1
  61.     Dim r As Integer
  62.     r = AcdbEntMake(ct, cv)
  63.     Debug.Print r
  64.     If r = 5100 Then
  65.         testAcdbEntMakeCircle
  66.         testAcdbEntMakeEndBlock
  67.     End If
  68. End Sub
发表于 2014-7-28 09:39:33 | 显示全部楼层
太好了,下来试试
发表于 2014-9-28 17:21:32 | 显示全部楼层
请问如何使用,我的系统是WIN7旗舰版32位,CAD是32位2010的,注册DLL是出现如下错误:

注册同名tlb文件也出现错误,请问一下高手该如何使用。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x
发表于 2014-9-28 23:30:43 | 显示全部楼层
想法非常好,求支持x64各版本,最好开源,能让大家一起帮忙。。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-11-24 19:35 , Processed in 0.180873 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表