林霄云 发表于 2014-4-22 23:48:38

引线标注点筋与线筋源码解析(支持UCS)

本帖最后由 林霄云 于 2014-4-23 22:09 编辑

引线标注点筋与线筋源码解析(支持UCS)
我曾说,我会离开lisp。谁又知道我从软件工程转土木工程有多难,又知道我内心有燃烧过那热火。——记录与真实生活
闲话少说,看正文。
思路
将标注点筋和线筋(一个标根数一个是标间距)集成在一起。应该做如下几件事:
1,选择后的选择集,自动判断是标注点筋还是线筋。
如果有点筋,标注点筋,如果没有点筋,标注线筋。
2,引线自动生成。
对于点筋,取点筋中点,如果是块,该是插入点,作为引线一端。对于线筋,取选择框中点距对象最近的点。且各自成前处理函数,生成点表。
取点筋点表(defun get_bar_ptlist( ss / pt_list pt en ent ptli )
;函数get_bar_ptlist,参数ss 选择集。返回值,点筋点表。
;Desiged by 林霄云 2014年2月10日取线筋点表(defun get_linebar_pt( ss / pt sslist )
;Designed by 林霄云 2014年4月20日
;取线筋接触点。多选时,仅支持取第一根3,动态处理文字位置,且为当前UCS下,支持90度旋转
对文字及文字下划线,拖动模式,更新其坐标点。旋转时,亦更新相应坐标点。
4,支持平行引线
当点筋标注时,在左击确认时,增加剩余平行引线。
5,最后间距按全局比例设置。
如果按固定的1:100出图,文字与文字下划线设为100便可。但支持墙柱配筋大样和墙身配筋大样,必然得支持自动复合相应的比例间距。
主函数解析:
dimbar(ptlist dotflag),ptlist为引线端点点表,由前述两函数获得,dotflag为点筋与否标识。
函数内的flag为动态退出标志;ang为文字角度(defun dimbar (ptlist dotflag / len pt str qline qtext box box-len tline flag ptr ptu-u ang pto1 pto2 pto pt-x pt-y i )
(setq flag t )
(setq ang 0)

;务必支持全局比例hnu:dimscale
(if (null hnu:dimscale)
(setq hnu:dimscale 100)
);if

(setq len (length ptlist))
(setq pt (car ptlist));只处理一根引线作为动态。
(setup "symbol");这句为设置图层,setup为一函数,以后提供

(if dotflag (setq str (strcat (itoa len) "%%13220")) (setq str "%%1328@200"));if 处理输入
(if (null dotflag) (make_insert pt "_ARCHTICK" (* 1.5 hnu:dimscale) pi (getvar "clayer")));if 处理线筋符号


(setq qline (make_line (list pt (setq ptu (offset_point pt hnu:dimscale 0 0))) (getvar "clayer") ));qline 斜引线,初始值,pt,与任意点
(setq qtext (make_text_b ptu ang (* 3.0 hnu:dimscale) 1 str (getvar "clayer")))            ;qtext 文字,高度与全局比例相关,对齐方式,中
(setq box (get_textbox qtext)
   box-len (+hnu:dimscale (* 0.5 (distance (car box) (cadr box)))))

(setq tline (make_line (list ptu (setq pte (offset_point ptu box-len 0 0)))(getvar "clayer")))       ;tline 文字下划线,初始值随意

(prompt "\n确定文字位置,逆时针旋转R,顺时针旋转E,撤销U")

      (while (and (setq ptr (grread t 15 2))
            (not (and (= 2 (car ptr)); 键盘事件
                  (or (= 13 (cadr ptr)) (= 32 (cadr ptr))) ;_Enter Space
            ))
             (not (or (= (car ptr) 11) (= (car ptr) 25)));_Mouse Right button
         flag
                        )   
               ; (redraw)
      (cond ((= (car ptr) 3);_Mouse Left button
          (setq ptu-u (cadr ptr))
          (setq ptu-w (trans ptu-u 1 0))
          (set-dxf qtext 11 ptu-w)
          (set-dxf tline 10 (setq pto1 (offset_point ptu-w (- box-len) (- hnu:dimscale) ang)))
          (set-dxf tline 11 (setq pto2 (offset_point ptu-w box-len (- hnu:dimscale) ang)))
          (if (< (distance pt pto1) (distance pt pto2))(setq pto pto1)(setq pto pto2))
          (set-dxf qline 11 pto)
          ;点筋加入引线
          (if (<= len 4);一般点筋少于等于4进行如此标注。
          (progn
          (setq i 0)
          (repeat (1- len)
          (setq i (1+ i))
          (setq pt-x (nth i ptlist) )
          (setq pt-y (inters pt-x (offset_point pt-x 100 0 (angle (get-dxf 10 qline)(get-dxf 11 qline))) pto1 pto2 nil))
          (make_line (list pt-x pt-y) (getvar "clayer"))
          (if (< (distance pto1 pt-y)(distance pto2 pt-y))
          (if (< (distance pto1 pto2)(distance pto2 pt-y));确保在点在外面
          (set-dxf tline 10 pt-y)
          )
          (if (< (distance pto1 pto2)(distance pto1 pt-y));确保在点在外面
          (set-dxf tline 11 pt-y)
          )
          )
          );repeat
          ));if len
          ;点筋加入引线
          (setq flag nil)
         ))
      (cond ((= (car ptr) 5)
          (setq ptu-u (cadr ptr))      ;很明显ptu-w为uCS下
          (setq ptu-w (trans ptu-u 1 0));很明显ptu-w为wCS下
            
          (set-dxf qtext 11 ptu-w)                           ;设置 qtext位置。
          (set-dxf tline 10 (setq pto1 (offset_point ptu-w (- box-len) (- hnu:dimscale) ang)));修正文字下划线tline位置。
          (set-dxf tline 11 (setq pto2 (offset_point ptu-w box-len (- hnu:dimscale) ang)))    ;修正文字下划线tline位置
          (if (<= (distance pt pto1) (distance pt pto2))(setq pto pto1)(setq pto pto2))      ;修正引线qline位置,其一端为文字下划线最近点
          (set-dxf qline 11 pto)      
          ))
      (cond ((= (car ptr) 2);键盘事件
         ; (if (or (= (ascii "S") (cadr ptr)) (= (ascii "s") (cadr ptr))) (command "scale" ss "" pt 0.5))
         ; (if (or (= (ascii "A") (cadr ptr)) (= (ascii "a") (cadr ptr))) (command "scale" ss "" pt 2))
          (if (or (= (ascii "R") (cadr ptr)) (= (ascii "r") (cadr ptr)))
          (progn (command "rotate" qtext tline "" ptu-u 90) (setq ang (+ ang (* 0.5 pi)))
          (setq pto1 (get-dxf 10 tline)
            pto2 (get-dxf 11 tline))
          (if (<= (distance pt pto1) (distance pt pto2))(setq pto pto1)(setq pto pto2))    ;修正引线qline位置,其一端为文字下划线最近点
          (set-dxf qline 11 pto))
          )
          (if (or (= (ascii "E") (cadr ptr)) (= (ascii "e") (cadr ptr)))
          (progn (command "rotate" qtext tline "" ptu-u -90) (setq ang (- ang (* 0.5 pi)))   
          (setq pto1 (get-dxf 10 tline)
            pto2 (get-dxf 11 tline))
          (if (<= (distance pt pto1) (distance pt pto2))(setq pto pto1)(setq pto pto2))    ;修正引线qline位置,其一端为文字下划线最近点
          (set-dxf qline 11 pto))
          )
         ; (if (or (= (ascii "E") (cadr ptr)) (= (ascii "e") (cadr ptr))) (command "rotate" ss "" pt -90))
          (if (or (= (ascii "U") (cadr ptr)) (= (ascii "u") (cadr ptr)))
          (progn
          (entdel qtext)(entdel qline)(entdel tline)(setq flag nil))
          ) ;删除ss,同时退出循环。
            ))
         );while

)主函数做的事情是,接收输入,生成文字,文字下划线,引线。然后动态调整其端点。
值得注意的是,1,get_textbox为我以前文章中的取文本四角点,offset_point为比polar更直观的求点自定义函数。2,make_text_b为,make_line自定义生成对象的函数,get-dxf,set-dxf为组码获得与更新。3,动态中,鼠标当前点,使用UCS,WCS系两点保存。
调用函数代码(defun C:dba( / ss ptlist )
;Designed by 林霄云 2014年4月20日
;dim bar 标注点钢筋与线钢筋

(setq ss (ssget '((0 . "INSERT,*LINE")))) ;最好加上钢筋图层控制
(if ss
(progn
(setq ptlist (get_bar_ptlist ss))       ;有点筋么?
(if ptlist
(progn
(dimbar ptlist t )
);progn
(progn
(setq pt (get_linebar_pt ss))      ;有线筋么?
(if pt
(dimbar (list pt) nil )
)
);progn
);if

));if ss

(princ)
);defun
还是得强调钱处理函数,代码给上,处理点筋点表(defun get_bar_ptlist( ss / pt_list pt en ent ptli )
;函数get_bar_ptlist,参数ss 选择集。返回值,点筋点表。
;Desiged by 林霄云 2014年2月10日
;(setq ss (ssget '((0 . "INSERT,LWPOLYLINE"))));由用户任意选择TEXT实体 用于测试
(setq pt_list nil)
(foreach en (SS2ENLIST ss)
(setq ent (entget en))
(setq typ (get-dxf 0 en))
(cond
((= typ "INSERT")
(if (= (get-dxf 2 en) "点筋") (setq pt (get-dxf 10 en)) (setq pt nil));if ;块插入点,WCS
)
((= typ "LWPOLYLINE")

;如果是点筋,取中点
(if (and (= (get-dxf 90 en) 2)
   (= (abs(get-dxf 42 en)) 1))
(setq pt (mid_point (car (setq ptli (get_pline_vertex en))) (cadr ptli)))
(setq pt nil)
);if
)
);cond
(if pt
(setq pt_list (cons pt pt_list))
)
);foreach
(reverse pt_list)
)比较难搞的线筋点表,敢情是最原创的东西,使用ssnamex函数。(defun get_linebar_pt( ss / pt sslist )
;Designed by 林霄云 2014年4月20日
;取线筋接触点。多选时,仅支持取第一根
;(setq ss (ssget '((0 . "INSERT,LWPOLYLINE"))))

(setq sslist (ssnamex ss 0))
(cond((= (caar sslist) 1)(setq pt (cadr (last (car sslist)))))
   ((or (= (caar sslist) 2)(= (caar sslist) 3)) (setq pt (mid_point (last(cadr (last sslist))) (last (cadddr (last sslist)))))
   ;(command "line" "non" (last(cadr (last sslist))) "non" (last(caddr (last sslist))) "non" (last(cadddr (last sslist))) "non" (last(last(last sslist)))"c") ;测试代码
   )
);cond
;如果是线筋,取最近点
(setq pt (vlax-curve-getClosestPointTo (vlax-ename->vla-object (ssname ss 0)) pt t));pt均为WCS下。
;(command "line" "non" (list 0 0) "non" (trans pt 0 1) "")
)鉴于代码中预留的解析比较详细,就不赘言了。所有的思路与步骤都已经给上。
结果
详测试图。
结论
基本完美的实现了,动态的,支持UCS的,智能判断的(文字处理,不提供输入,二是进行默认处理,是我自己的见解)点筋线筋标注集成命令。
(本文是我原创的最后一个功能,以后可能不做了,但已有的未发表的,将择机择日发布,附件中是还待整理的通用函数)
预告
1,墙线绘制源码解析(支持UCS,偏心或居中布置,厚度设置,自动填充)
2,梁线绘制源码解析(支持偏心或居中布置,宽度设置,梁线十字裁剪,梁截面标注,生成梁中轴线)

林霄云 发表于 2014-4-23 13:29:43

根据两点原则,1、不过度设计,避免多余错误。2、不过多操作。
基于此,我不断的看自己作品的演示图,以期有更合适的操作,更清晰的概念。
对于引线是多引线还是单引线,原文为;点筋加入引线
          (if (<= len 4);一般点筋少于等于4进行如此标注。现修改为;点筋加入引线
          (if (> len 1);得到更清晰的效果是,左击,便是多引线。其他情况,为单引线。更为清晰。于是,提示改为 (prompt "\n确定文字位置,逆时针旋转R,顺时针旋转E,撤销U,左击为多引线")

lucas_3333 发表于 2014-4-23 00:30:07

辛苦了,写这么一大篇,只是隔行与隔山,完全看不懂。

↘觉醒 发表于 2016-5-3 21:53:32

版主我加载了,不知道命令是什么?怎么用呀

树櫴希德 发表于 2014-4-23 09:59:54

虽然不懂,但也要强烈支持

firstinti 发表于 2014-4-23 10:10:31

非常有用,感谢楼主的无私精神

xyp1964 发表于 2014-4-23 10:36:39

不错!
最好提供一个dwg测试文件

林霄云 发表于 2014-4-23 10:47:15

xyp1964 发表于 2014-4-23 10:36 static/image/common/back.gif
不错!
最好提供一个dwg测试文件

可以不要的

enn09 发表于 2014-4-23 10:51:53

非常有用,感谢楼主的无私精神,期待墙线的源码放出!

林霄云 发表于 2014-4-23 11:12:55

(if (null dotflag) (make_insert pt "_ARCHTICK" (* 1.5 hnu:dimscale) pi (getvar "clayer")));if 处理线筋符号在后面的撤销过程中,亦应有相应的删除操作。(if (null dotflag) (entdel (ssname (ssget (trans pt 0 1) '((0 . "INSERT")(2 . "_ARCHTICK"))) 0)));pt "_ARCHTICK" ;ssget ucs坐标系的点,处理第一个。

机械工程师 发表于 2014-4-23 13:15:03

林兄很给力啊。
页: [1] 2 3 4 5 6 7
查看完整版本: 引线标注点筋与线筋源码解析(支持UCS)