brbright 发表于 2015-4-9 13:08:00

[源码+教程]使用AutoLisp在动态块中实现动作和约束的混合使用

使用AutoLisp在动态块中实现动作和约束的混合使用
作者:BrightRat
时间:2015年04月09日
Contents
1 联合使用动作和约束的重要性
1.1 什么是含约束参数的动态块
1.2为什么要使用约束参数
1.3 什么是含动作参数的动态块(简称动作块)
1.4 联合使用动态块中的动作和约束。
2.理清编程思路
2.1 准备约束块和动作块。
2.2 需要用到的动态块函数及其形参类型
3 AutoLisp编程实例
3.1 程序源码
3.2 程序功能
4 寻找动态块约束参数支持的函数
5 结束语
附件中的cad文件预览






**** Hidden Message *****

被承包的东子 发表于 2020-10-29 16:53:00

感谢分享,马克一下,后面要用,动态块的应用

xjshaha 发表于 2022-7-25 22:07:00


这个太高级了,先留下标记再学习

guankuiwu 发表于 2019-12-11 14:08:00

这个太高级了,先留下标记再学习

brbright 发表于 2015-4-9 13:18:00

1 联合使用 动作和约束的重要性
1.1 什么是含约束参数的动态块
AutoCAD 2010以后,可以使用强大的约束功能。
我们知道,如果要将一条直线三等分,可以使用DIVIDE命令。如果要将一个对象三等分,那么我们可以作一条辅助线,DIVIDE三等分,利用辅助点,再作两条辅助线来实现。
这样子其实非常繁琐。


如上图所示。我们可以制作一个含约束参数的动态块。
约束块中的参数:d1、d2、d3;
约束参数关系:d2=d1/3,d3=d1/3;


只要拖动一个约束块的夹点,会自动作出三等分的区间,直接用于辅助绘图。
1.2为什么要使用约束参数


如上图所示,一单跨简支梁,上部钢筋较长时,需要在支座中心线1/3处断开。如果不依赖其他详图插件,纯手工CAD作图,divide命令要频繁使用,相当枯燥。另外,divide命令没有办法做取整处理,如下所示:
梁长:L1=9256mm
三分点:L1/3=3085.333mm
向上取整后:3090mm
将3085.333取整为3090而不是3086,是因为单位为毫米的尺寸没有必要,过高的精度反而会让施工现场读图者烦躁。稍大一点的项目会有成百上千条结构梁,这些取整操作常常会让绘图员和计算器绝望。
熟悉Excel的朋友会尝试使用编函数表的方式来解决这些计算。
A2                =A2/3                   =ROUND((A2/3+5)/10,0)*10
4144      1381.333333         1390
5648      1882.666667         1890
6371      2123.666667         2130
7486      2495.333333         2500
8539      2846.333333         2850
9655      3218.333333         3220
因为要频繁切换AutoCAD和Excel,打断作图思路,实际操作并不比手边的计算器方便。
值得高兴的是,我们可以直接使用约束块一次性完成这些计算和绘图操作。


约束块中的参数:
d1
d2=ROUND((d1/3+5)/10)*10
d3=ROUND((d1/3+5)/10)*10


只要拖动一个夹点,三等分和取整的操作会自动完成。


将三等分梁、取整和作辅助线的操作交给CAD,提高绘图效率。
1.3 什么是含动作参数的动态块(简称动作块)


制作一个动态块,分别在两个钢筋打断点处定义两个距离参数,然后从梁长中分点处往两边再定义两个距离参数,用DDEDIT命令将他们修改为D1、D2和E1、E2。将这四个参数的动作都定义为拉伸。


拖动这四个夹点,自动调整钢筋打断点的位置和左右方向的梁长。
1.4 联合使用动态块中的动作和约束。
动作参数强在图形编辑能力,约束参数的优点是自动计算。
有没有办法将他们结合在一起用呢?
约束参数的逻辑是点之间的固有关系,动作参数的逻辑是外力的作用。AutoCAD不建议将他们混合使用。笔者尝试过将两者放在同一个块里,结果是动态块不能工作。
于是,笔者将两种参数分别定义一个动态块,然后使用Lee-Mac提供的动态块修改函数将他们联系在一起。

brbright 发表于 2015-4-9 13:22:00

2. 理清编程思路
2.1 准备约束块和动作块。
动作块直接使用上文定义的单跨梁-动作块,将参数E1+E2即可取得梁长。


约束块直接使用上文中的三分取整块。将梁长(E1+E2)输入到d1,自动计算d2取得三分取整长度。


然后将计算得出的三分取整长度d2输入到单跨梁-动作块的参数A1和A2中,自动完成钢筋断点位置的作图。
2.2 需要用到的动态块函数及其形参类型 ;; 获取动态块的属性-LeeMac;; 返回动态块的一个属性值 (如果存在);; blk - VLA 类型动态块数据;; prp - str 类型的动态块属性名称(不分大小写)(defun LM:getdynpropvalue (blk prp) (setq prp (strcase prp)) (vl-some '(lambda (x)            (if (= prp (strcase (vla-get-propertynamex)))            (vlax-getx 'value)            )          )         (vlax-invoke blk 'getdynamicblockproperties)));; 设置动态块的属性值-LeeMac;; 修改一个动态块的属性值(如果存在);; blk - VLA 类型的动态块数据;; prp - str 类型的动态块属性名称(不分大小写);; val - 新的动态块属性(数据类型随系统,常见为string);; 返回: 新的动态块属性(如果成功,否则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)))

brbright 发表于 2015-4-9 13:24:00

3 AutoLisp编程实例3.1 程序源码以下的程序经过认真注释,可读性较强。 ;;加载vlisp拓展(vl-load-com) ;;;;-----通用函数----- ;; 获取动态块的属性-LeeMac;; 返回动态块的一个属性值 (如果存在);; blk - VLA 类型动态块数据;; prp - str 类型的动态块属性名称(不分大小写)(defun LM:getdynpropvalue (blk prp) (setq prp (strcase prp)) (vl-some '(lambda (x)            (if (= prp (strcase (vla-get-propertynamex)))            (vlax-getx 'value)            )          )         (vlax-invoke blk 'getdynamicblockproperties)));; 设置动态块的属性值-LeeMac;; 修改一个动态块的属性值(如果存在);; blk - VLA 类型的动态块数据;; prp - str 类型的动态块属性名称(不分大小写);; val - 新的动态块属性(数据类型随系统,常见为string);; 返回: 新的动态块属性(如果成功,否则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-----;;设置用于数据运算的动态块,保存在变量dx_paradyn中(defun c:was();;取得用于数据运算的动态块(含约束参数) (setq dx_paradyn (vlax-ename->vla-object (car (entsel)))) (princ));;;;-----主程序2-----;;数据运算并修改动态块(defun c:wa();;取得用于需要修改的动态块,保存在变量dx_actdyn中 (setq dx_actdyn (vlax-ename->vla-object (car (entsel))));;取得动态块的特定属性值;;此处,E1和E2为左右半跨梁长 (setq dyn_act_e1 (LM:getdynpropvalue dx_actdyn "E1")) (setq dyn_act_e2 (LM:getdynpropvalue dx_actdyn "E2"))    ;;经测试,dyn_act_e1、dyn_act_e2的数据类型为real,直接将他们相加作为梁长 (setq d_real_e1_e2 (+ dyn_act_e1 dyn_act_e2));;转换梁长数据d_real_e1_e2为string类型 (setq d_str_e1_e2 (rtos d_real_e1_e2));;将梁长输入到用于数据运算的动态块dx_paradyn的参数d1中 (LM:setdynpropvalue dx_paradyn "d1" d_str_e1_e2);;调用CAD内置命令REGEN,更新动态块数据(重要) (command "REGEN");;取得动态块的特定属性值;;此处,d2为含约束参数的动态块,三分取整后的长度 (setq dyn_para_d2 (LM:getdynpropvalue dx_paradyn "d2"));;转换三分取整后的长度数据dyn_para_d2为string类型 (setq d_str_d2 (rtos dyn_para_d2));;修改动态块dx_actdyn,调整钢筋搭接位置参数A1、A2 (print d_str_d2) (LM:setdynpropvalue dx_actdyn "A1" d_str_d2) (LM:setdynpropvalue dx_actdyn "A2" d_str_d2) (princ)) 3.2 程序功能


利用AutoLisp联合使用约束参数和动作参数,将三分点计算和取整的操作交给CAD,可以减轻绘图员的计算量,提高绘图效率。

brbright 发表于 2015-4-9 13:25:00

4 寻找动态块约束参数支持的函数 下面是CAL命令支持的函数(摘抄至AutoCAD帮助),动态块应该能用(未完全测试)。   Use StandardNumeric Functions (CAL Command)CAL supports the standard numeric functions in the followingtable.Numeric functionsFunctionDescriptionsin(angle)Sine of the anglecos(angle)Cosine of the angletang(angle)Tangent of the angleasin(real)Arcsine of the number; the numbermust be between -1 and 1acos(real)Arccosine of the number; the numbermust be between -1 and 1atan(real)Arctangent of the numberln(real)Natural log of the numberlog(real)Base-10 log of the numberexp(real)Natural exponent of the numberexp10(real)Base-10 exponent of the numbersqr(real)Square of the numbersqrt(real)Square root of the number; thenumber must be nonnegativeabs(real)Absolute value of the numberround(real)Number rounded to the nearestintegertrunc(real)Integer portion of the numberr2d(angle)Angles in radians converted todegrees;   for example, r2d(pi) converts thepi radians to 180 degreesd2r(angle)Angles in degrees converted toradians;   for example, d2r(180) converts180 degrees to radians and returns the value of pipiThe constant pi   Numeric operators    OperatorOperation( )Groups expressions^Indicates exponentiation* , /Multiplies, divides+, -Adds, subtracts   Vector operators    OperatorOperation( )Groups expressions&Determines the vector product of vectors (as a vector)& = [ (b*z) - (c*y) , (c*x) - (a*z) ,(a*y) - (b*x) ]*Determines the scalar product of vectors (as a realnumber)

brbright 发表于 2015-4-9 13:28:00

5 结束语
本文在开始介绍了动态块中,动作参数和约束参数的功能,然后利用AutoLisp将他们结合起来,为参数化绘图和程序设计提供了一种实现方法。

rhww 发表于 2015-4-9 13:31:00

受你的启发,应该可以搞一个自动计算点钢筋个数的动态块
页: [1] 2
查看完整版本: [源码+教程]使用AutoLisp在动态块中实现动作和约束的混合使用