[源码+教程]使用动态块函数简化AutoLisp参数设计编程
本帖最后由 brbright 于 2015-4-2 09:40 编辑使用动态块函数简化AutoLisp编程(少用三角函数)作者:BrightRat时间:2015年04月02日
1 动态块在参数化设计编程中的重要性
您可知,《AutoCAD程序设计魔法书–AutoLisp&DCL基础篇》第五章有提到,参数设计的关键技巧是熟知三角函数关系。
没错,熟知三角函数可以精确地掌握点线面之间的关系,绘制出所需要的目标图形。
但是,如果图元稍稍增加一点,需要控制的对象之间的相对关系就会变得复杂起来,并使得需要编写的程序代码成倍的增长并且难以维护。尤其在需要紧急编写可用程序的时候,会使编程人员感到非常烦恼。
别急,自AutoCAD2006以后,我们可以使用非常强大的动态块,为小型绘图程序的编程带来便利。
请注意,本文中的动态块函数来自于Lee-Mac,在AutoCAD2008中文版中测试通过。程序代码在AutoCAD2014英文版中测试通过,AutoCAD2007版或以上应该能用(未测试)。更多有关动态块函数的信息,您可以到Lee-Mac的博客(英文)查询。
这是附件中的CAD文件预览:
很好→很棒!很好~很棒!!很好……很棒!!!
我觉得要是能针对箍筋与之配合使用的主筋直径→对应其转弯半径→那就完美了!
甚至还能根据抗震等级调整箍筋弯钩的长度! 2 问题的提出 – 绘制大量角度不规则的建筑混凝土结构箍筋
2.1 已有的图纸
2.2 目标图纸:
3 编程前的准备
3.1 动态块拉筋
制作一个动态块拉筋,参数是D1,动作是拉伸。
使之可以方便的通过拖动夹点,自动拉伸。旋转不影响拉伸功能。
3.2 动态块箍筋
制作一个动态块箍筋,参数是D1和D2,动作分别为两个方向的拉伸。
使之可以方便的通过拖动夹点,在两个方向上自动拉伸。旋转不影响拉伸功能。
论坛关于动态块的帖子不多 看这次楼主带来什么新东西 4 理清编程思路
如果不使用LSP和其他插件,我们可以利用CAD自带的ALIGN对齐命令,使用4点捕捉的方式,可以一次性的完成块的平移和旋转动作。
然后对平移和旋转后的动态块,使用拖动动作夹点的拉伸方法,可以很方便的编辑,使之达到我们想要的效果。
最后通过复制拉伸后的动态块,完成作图目标。
然而,我们可以使用AutoLisp编程的方法,将上述过程简化。
具体思路:
4.1 使用 vla-copy函数复制一个动态块。
4.2 使用 command函数调用CAD的ALIGN命令平移和旋转复制后的动态块。
4.3 使用 lee-mac提供的动态块修改函数,修改目标参数D1、D2等。
5 重要关键 - Lee-Mac动态函块数需要的形参数据类型
;;-----通用函数:设置动态块参数(源自LEE-MAC)
;;来源网站http://www.lee-mac.com/dynamicblockfunctions.html
;; 修改动态块的参数(如果存在)
;; blk - 数据类型为VLA的动态块
;; prp - 数据类型为字符串的动态块参数
;; val - 动态块参数的数值,数据类型根据系统定义,常见为字符串
;; 返回: 新的动态块参数(如果成功), 否则返回nil
(defun LM:setdynpropvalue ( blk prp val )
(setq prp (strcase prp))
(vl-some
'(lambda ( x )
(if (= prp (strcase (vla-get-propertyname x)))
(progn
(vla-put-value x (vlax-make-variant val (vlax-variant-type (vla-get-value x))))
(cond (val) (t))
)
)
)
(vlax-invoke blk 'getdynamicblockproperties)
)
)
6 开始编程-动态块拉筋
下面的程序经过认真注释,朋友们不用当心难以阅读。
;;加载VlISP拓展
(vl-load-com)
;;-----通用函数:设置动态块参数(源自LEE-MAC)
;;来源网站http://www.lee-mac.com/dynamicblockfunctions.html
;; 修改动态块的参数(如果存在)
;; blk - 数据类型为VLA的动态块
;; prp - 数据类型为字符串的动态块参数
;; val - 动态块参数的数值,数据类型根据系统定义,常见为字符串
;; 返回: 新的动态块参数(如果成功), 否则返回nil
(defun LM:setdynpropvalue (blk prp val)
(setq prp (strcase prp))
(vl-some
'(lambda (x)
(if (= prp (strcase (vla-get-propertyname x)))
(progn
(vla-put-value
x
(vlax-make-variant
val
(vlax-variant-type (vla-get-value x))
)
)
(cond (val)
(t)
)
)
)
)
(vlax-invoke blk 'getdynamicblockproperties)
)
)
;;-----程序集1:一个参数动态块的复制、旋转、参数调整-------------------------------
;;-----程序1.1:设置动态块标注源
;;本程序用于取得参考用的动态块和用于ALIGN平移旋转定位的两个点
(defun c:rds ()
(setq d_dynbx1_1 (car (entsel "\n请选择源动态块")))
(setq d_dynbx1_point_1
(getpoint "\n请选择源动态块的平移基点(align的第一点)"
)
)
(setq d_dynbx1_point_2
(getpoint
"\n请选择源动态块的角度对齐点(align的第三点)"
)
)
;;lisp对象转换为vl对象,用于vla-copy函数
(setq dx_dynbx1_1 (vlax-ename->vla-object d_dynbx1_1))
)
;;-----程序1.2:复制动态块到指定位置并设置参数
;;本程序先在原地复制一个动态块,
;;然后根据选择的两个点将复制后的动态块ALIGN平移、旋转
;;最后计算选择的两个点之间的距离,修改移动后的动态块
(defun c:rd ()
(setq
t_point_3 (getpoint "\n请选择复制动态块的平移基点(align的第二点)")
)
(setq
t_point_4
(getpoint "\n请选择复制动态块的角度对齐点(align的第四点)")
)
;;复制一个动态块
(setq tx_dynbx1_2 (vla-copy dx_dynbx1_1))
;;vl对象转换为lisp对象,用于align命令
(setq t_dynbx1_2 (vlax-vla-object->ename tx_dynbx1_2))
;;调用CAD的内置命令align实现动态块的平移和转角对齐
(command "align" t_dynbx1_2 "" d_dynbx1_point_1
t_point_3 d_dynbx1_point_2 t_point_4
"" "n"
)
;;计算复制后的动态块基点到对齐点的距离
(setq t_dynbx1_dist_1 (rtos (distance t_point_3 t_point_4)))
;;调用动态块设置函数,设置复制后的动态块的参数
;;设置参数distance1
(LM:setdynpropvalue
tx_dynbx1_2
"D1"
t_dynbx1_dist_1
)
(princ)
)
7 使用动态块的好处-以箍筋为例
7.1 使用动态块的好处一:已于拓展
通过上例,我们了解到,利用动态块编程的方式,可以避免各个定位点之间繁琐的三角函数关系运算。
按正常的编程思路,我们至少需要知道拉筋中间直线两端的两个点,拉筋两端的两个弯钩圆心,以及弯钩后钢筋伸长锚固直线的端点,共6个参数点之间的关系。之后还要反复调用直线和圆弧的绘图命令才能完成作图。
然而,如果我们使用动态块,读者可以注意到,我们实质上仅仅只需调用distance函数一次,计算两个点间的距离,即可完成编程任务,并节省大量不必要的代码。
如果您的数学功底比较好,可能不在意以上6个参数点。
现在,我们继续下一个任务:使用程序绘制箍筋。
首先,对需要计算参数点进行初步估计:
从上图可以看到,按常规的编程思路,不需找某种“技巧性”的编程方法,我们需要考虑12个点之间的坐标三角函数关系,然后使用直线和圆弧将之连起来。可以想象,这种编程的思路,需要比较扎实的数学基础,参数量和代码函数都比较可观。
但是,如果使用动态块,可以节省不少代码,降低思考强度。
;;-----程序2:两个参数动态块的复制、旋转、参数调整-------------------------------
;;-----程序2.1:设置动态块标注源
;;本程序用于取得参考用的动态块和用于ALIGN平移旋转定位的两个点
;;将本程序rd2s和上面的rds程序比对,可以发现,除了改变几个参数的名称,完全是一模一样的。
;;加载VlISP拓展
(vl-load-com)
;;-----通用函数:设置动态块参数(源自LEE-MAC)
;;来源网站http://www.lee-mac.com/dynamicblockfunctions.html
;; 修改动态块的参数(如果存在)
;; blk - 数据类型为VLA的动态块
;; prp - 数据类型为字符串的动态块参数
;; val - 动态块参数的数值,数据类型根据系统定义,常见为字符串
;; 返回: 新的动态块参数(如果成功), 否则返回nil
(defun LM:setdynpropvalue (blk prp val)
(setq prp (strcase prp))
(vl-some
'(lambda (x)
(if (= prp (strcase (vla-get-propertyname x)))
(progn
(vla-put-value
x
(vlax-make-variant
val
(vlax-variant-type (vla-get-value x))
)
)
(cond (val)
(t)
)
)
)
)
(vlax-invoke blk 'getdynamicblockproperties)
)
)
(defun c:rd2s ()
(setq d_dynbx2_1 (car (entsel "\n请选择源动态块")))
(setq d_dynbx2_point_1
(getpoint "\n请选择源动态块的平移基点(align的第一点)"
)
)
(setq d_dynbx2_point_2
(getpoint
"\n请选择源动态块的角度对齐点(align的第三点)"
)
)
;;lisp对象转换为vl对象,用于vla-copy函数
(setq dx_dynbx2_1 (vlax-ename->vla-object d_dynbx2_1))
)
;;-----程序2.2:复制动态块到指定位置并设置参数
;;本程序先在原地复制一个动态块,
;;然后根据选择的两个点将复制后的动态块ALIGN平移、旋转
;;最后计算选择的三个点之间的距离,修改移动后的动态块
;;将本程序rd2和上面的rd比对,只增加了3行代码,新增的代码会在下面提示。
;;可以看到,新增的代码是很简单的,功能和邻近的代码完全一样,不需要创新的思路。
(defun c:rd2 ()
(setq
t_point_3 (getpoint "\n请选择复制动态块的平移基点(align的第二点)")
)
(setq
t_point_4
(getpoint "\n请选择复制动态块的角度对齐点(align的第四点)")
)
;;------此处是新增的代码1-------
(setq t_point_5 (getpoint
"\n请选择复制动态块参数点(用于计算到基点的距离)"
)
)
;;------上面是新增的代码1-------
;;复制一个动态块
(setq tx_dynbx2_2 (vla-copy dx_dynbx2_1))
;;vl对象转换为lisp对象,用于align命令
(setq t_dynbx2_2 (vlax-vla-object->ename tx_dynbx2_2))
;;调用CAD的内置命令align实现动态块的平移和转角对齐
(command "align" t_dynbx2_2 "" d_dynbx2_point_1
t_point_3 d_dynbx2_point_2 t_point_4
"" "n"
)
;;分别计算复制后的动态块基点道对齐点和参数点的距离
(setq t_dynbx2_dist_1 (rtos (distance t_point_3 t_point_4)))
;;------此处是新增的代码2-------
(setq t_dynbx2dist_2 (rtos (distance t_point_3 t_point_5)))
;;------上面是新增的代码2-------
;;调用动态块设置函数,设置复制后的动态块的参数
;;设置参数distance1
(LM:setdynpropvalue
tx_dynbx2_2
"D1"
t_dynbx2_dist_1
)
;;------此处是新增的代码3-------
;;设置参数distance2
(LM:setdynpropvalue
tx_dynbx2_2
"D2"
t_dynbx2dist_2
)
;;------上面是新增的代码3-------
(princ)
)
7.2 使用动态块的好处二:易于维护
细心的建筑结构同行会发现,上文中的箍筋明显漏画了弯钩。
如果是常规的编程方法,我们会直接增加相关的带以满足新的功能。这将直接让编程人员继续研究各种三角函数以及运算,相当枯燥。
但是,在动态块中做点小改变却丝毫不费力气。
对于本例,加弯钩的动态块拉伸、移动动作和逻辑与未加拉钩前一模一样,动态块参数(D1、D2)保持不变。原来的代码无需任何修改可以直接使用。
8 结束语
本文通过常规编程与利用动态块编程的方法之间的对比,得出使用动态块可以减少编程时间和思考强度的结论。