明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 4108|回复: 24

[源码] [源码+教程]使用动态块函数简化AutoLisp参数设计编程

[复制链接]
发表于 2015-4-2 09:05 | 显示全部楼层 |阅读模式
本帖最后由 brbright 于 2015-4-2 09:40 编辑

使用动态块函数简化AutoLisp编程(少用三角函数)
作者:BrightRat
时间:2015年04月02日


1 动态块在参数化设计编程中的重要性
您可知,《AutoCAD程序设计魔法书–AutoLisp&DCL基础篇》第五章有提到,参数设计的关键技巧是熟知三角函数关系。

没错,熟知三角函数可以精确地掌握点线面之间的关系,绘制出所需要的目标图形。

但是,如果图元稍稍增加一点,需要控制的对象之间的相对关系就会变得复杂起来,并使得需要编写的程序代码成倍的增长并且难以维护。尤其在需要紧急编写可用程序的时候,会使编程人员感到非常烦恼。

别急,自AutoCAD2006以后,我们可以使用非常强大的动态块,为小型绘图程序的编程带来便利。

请注意,本文中的动态块函数来自于Lee-Mac,在AutoCAD2008中文版中测试通过。程序代码在AutoCAD2014英文版中测试通过,AutoCAD2007版或以上应该能用(未测试)。更多有关动态块函数的信息,您可以到Lee-Mac的博客(英文)查询。

这是附件中的CAD文件预览:

本帖子中包含更多资源

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

x

评分

参与人数 5明经币 +5 金钱 +50 收起 理由
wayne_myles + 1 很给力!
【KAIXIN】 + 1 + 50 赞一个!
USER2128 + 1 很给力!
zctao1966 + 1 很给力!
vectra + 1 很给力!

查看全部评分

本帖被以下淘专辑推荐:

 楼主| 发表于 2015-4-2 09:07 | 显示全部楼层
2 问题的提出 – 绘制大量角度不规则的建筑混凝土结构箍筋
2.1 已有的图纸

2.2 目标图纸:

本帖子中包含更多资源

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

x
 楼主| 发表于 2015-4-2 09:10 | 显示全部楼层
3 编程前的准备
3.1 动态块拉筋
制作一个动态块拉筋,参数是D1,动作是拉伸。

使之可以方便的通过拖动夹点,自动拉伸。旋转不影响拉伸功能。


3.2 动态块箍筋
制作一个动态块箍筋,参数是D1和D2,动作分别为两个方向的拉伸。

使之可以方便的通过拖动夹点,在两个方向上自动拉伸。旋转不影响拉伸功能。

本帖子中包含更多资源

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

x
发表于 2015-4-2 09:10 | 显示全部楼层
论坛关于动态块的帖子不多 看这次楼主带来什么新东西
 楼主| 发表于 2015-4-2 09:11 | 显示全部楼层
4 理清编程思路
如果不使用LSP和其他插件,我们可以利用CAD自带的ALIGN对齐命令,使用4点捕捉的方式,可以一次性的完成块的平移和旋转动作。
然后对平移和旋转后的动态块,使用拖动动作夹点的拉伸方法,可以很方便的编辑,使之达到我们想要的效果。
最后通过复制拉伸后的动态块,完成作图目标。

然而,我们可以使用AutoLisp编程的方法,将上述过程简化。

具体思路:
4.1 使用 vla-copy函数复制一个动态块。
4.2 使用 command函数调用CAD的ALIGN命令平移和旋转复制后的动态块。
4.3 使用 lee-mac提供的动态块修改函数,修改目标参数D1、D2等。

本帖子中包含更多资源

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

x
 楼主| 发表于 2015-4-2 09:12 | 显示全部楼层
5 重要关键 - Lee-Mac动态函块数需要的形参数据类型

;;-----通用函数:设置动态块参数(源自LEE-MAC)
;;来源网站http://www.lee-mac.com/dynamicblockfunctions.html
;; 修改动态块的参数(如果存在)
;; blk - [vla] 数据类型为VLA的动态块
;; prp - [str] 数据类型为字符串的动态块参数
;; val - [any] 动态块参数的数值,数据类型根据系统定义,常见为字符串
;; 返回: [any] 新的动态块参数(如果成功), 否则返回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)
    )
)
 楼主| 发表于 2015-4-2 09:13 | 显示全部楼层
6 开始编程-动态块拉筋
下面的程序经过认真注释,朋友们不用当心难以阅读。

;;加载VlISP拓展
(vl-load-com)
;;-----通用函数:设置动态块参数(源自LEE-MAC)
;;来源网站http://www.lee-mac.com/dynamicblockfunctions.html
;; 修改动态块的参数(如果存在)
;; blk - [vla] 数据类型为VLA的动态块
;; prp - [str] 数据类型为字符串的动态块参数
;; val - [any] 动态块参数的数值,数据类型根据系统定义,常见为字符串
;; 返回: [any] 新的动态块参数(如果成功), 否则返回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)
)
 楼主| 发表于 2015-4-2 09:15 | 显示全部楼层
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] 数据类型为VLA的动态块
;; prp - [str] 数据类型为字符串的动态块参数
;; val - [any] 动态块参数的数值,数据类型根据系统定义,常见为字符串
;; 返回: [any] 新的动态块参数(如果成功), 否则返回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)
)

本帖子中包含更多资源

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

x
 楼主| 发表于 2015-4-2 09:19 | 显示全部楼层
7.2 使用动态块的好处二:易于维护
细心的建筑结构同行会发现,上文中的箍筋明显漏画了弯钩。

如果是常规的编程方法,我们会直接增加相关的带以满足新的功能。这将直接让编程人员继续研究各种三角函数以及运算,相当枯燥。
但是,在动态块中做点小改变却丝毫不费力气。


对于本例,加弯钩的动态块拉伸、移动动作和逻辑与未加拉钩前一模一样,动态块参数(D1、D2)保持不变。原来的代码无需任何修改可以直接使用。

本帖子中包含更多资源

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

x
 楼主| 发表于 2015-4-2 09:19 | 显示全部楼层
8 结束语
本文通过常规编程与利用动态块编程的方法之间的对比,得出使用动态块可以减少编程时间和思考强度的结论。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-4-25 08:32 , Processed in 0.270897 second(s), 37 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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