过程选择集
我有一个旧的lisp例程,我们一直在使用它来创建DTEXT行之间的正确行距。此例程主要用于处理旧图形中的注释以创建修订。无论出于何种原因,大多数图纸上的注释都是单行的DTEXT,而不是多行文字。更糟糕的是,行距有点到处都是(即行与行之间的间距不同),作为****需要订单的人,这是完全不能接受的。无论如何,这个例程有几个问题影响了它的功能。首先,用户必须按顺序选择每行文本,以正确排序注释。当你有一整张F大小的便笺,并且你必须手动按顺序选择每一行文字时,它会变得非常乏味。
其次,用户必须手动输入行间距。这没那么糟糕,但我不想让用户决定。相反,我希望有两个选项,单间距或双间距,让用户从对话框中选择间距,或者只需键入“S”表示单间距,或键入“d”表示双间距(即,命令行看起来像这样:命令:选择间距选项(单/双):)
最后,在运行命令后,第一段文本看起来仍然是选中的。见下图。
按逃生键没有任何作用。用户必须在屏幕上选择其他内容,然后点击ESCAPE将其清除。我意识到这很琐碎,但它让我感到厌烦。
在前一段时间的另一篇帖子中,有人向我提到,用快速命令TXT2MTXT将DTEXT行组合成多行文字实体,这将在一个音符内的行之间创建正确的行距。然后我们要做的就是调整音符之间的间距。我把这个小消息传给了我们的团队,这就是我们最近一直在做的事情。
然而,随着我对学习lisp的深入研究,我决定修改现有的行距lisp例程,以纳入我上面列出的想法。问题是我不知道如何使用选择集。我在这里找到了下面的代码(来自Alanjt),我认为这有帮助:
(if (setq ss (ssget '((0 . "TEXT"))))
(vl-sort
((lambda (i / lst)
(while (setq e (ssname ss (setq i (1+ i))))
(setq lst (cons e lst))
)
)
-1
)
(function (lambda (a b) (> (caddr (assoc 10 (entget a))) (caddr (assoc 10 (entget b))))))
)
)
以下是我们的行距lisp中的代码:
; TXTSPC command is for adjusting the spacing between existing TEXT
; By G. Ramesh, NPCC, Abu Dhabi.
(defun C:TXTSPC (/ d e1 elist fpt el1 el2 sp1 sp2 r-ang dis dif i)
(setvar "highlight" 1)
(command ".undo" "g")
(setq d (getdist "\nSpacing required between lines: "))
(prompt
"\nSelect the TEXT entities one by one starting from the top . . ."
)
(setq e1 (entsel "\nSelect first TEXT: ")
elist '()
i 0
)
(while e1
(redraw (car e1) 3)
(setq elist (append elist (list (car e1)))
e1 (entsel "\nSelect next TEXT: ")
)
)
(foreach n elist (redraw n 1))
(setq el1 (entget (nth 0 elist)))
(if (/= (cdr (assoc 72 el1)) 0)
(setq code 11)
(setq code 10)
)
(setq fpt (cdr (assoc code el1)))
(repeat (1- (length elist))
(setq el1 (entget (nth i elist))
el2 (entget (nth (1+ i) elist))
sp1 (cdr (assoc code el1))
sp2 (cdr (assoc code el2))
r-ang (cdr (assoc 50 el1))
dis (- (cadr sp1) (cadr sp2))
dif (- d dis)
sp2 (polar fpt (- r-ang (/ pi 2)) (* (1+ i) d))
el2 (subst (append (list code) sp2) (assoc code el2) el2)
i (1+ i)
)
(entmod el2)
)
(foreach n elist (redraw n 1))
(command ".undo" "end")
(prin1)
)
我可以得到一些关于如何合并选择集的提示吗?在选择集中,实体根据其垂直位置与上述代码进行处理?我知道这是一篇很长的帖子,如果你读到这里,我很感激。
朗尼 假设:
所有文本都具有相同的对齐方式、文本高度、字体等
您希望所有文本左X轴对齐
您只想调整Y轴值
1.5 X文本高度的间距有点标准,
您需要该值的一倍或两倍
-大卫 大卫,
你所有的假设都是正确的。我知道还有很多更强大的文本对齐和间距例程。Lee Mac的动态文本对齐工具是一个很棒的程序,它只是我们所需要的。此外,我正在努力学习lisp,所以弄清楚如何修改现有的现实世界问题将有助于成为一名更好的程序员。
朗尼 事实上,你已经选择了一个非常难对付的1
逻辑需要遵循:
[列表]
[*]仅选择“文本”实体
[*]逐步通过集合
[*]找到最大Y值
[*]记录所有Y值及其各自实体的名称
[*]排序Y值并记录实体名称
[*]逐步遍历排序集
[*]根据预设的X轴和下降的Y轴值输入每个排序实体的点值
[/列表]
这不是一个真正简单的过程。
修改现有代码可能是一个真正的挑战。有时候最好从头开始
下面是我将如何开始这1的方法
(initget 1 "Single Double")
(setq ys (getkword "\nSpacing Style - Single/Double: "))
(and (setq i -1
ss (ssget '((0 . "TEXT"))))
(while (setq en (ssname ss (setq i (1+ i))))
(setq ed (entget en)
p10 (cdr (assoc 10 ed)))
(cond ((not maxy)
(setq maxy (cadr p10)
maxe en))
((> (cadr p10) maxy)
(setq maxy (cadr p10)
maxe en)))
(setq yl (cons (cons (cadr p10) en) yl)))
(setq fd (entget maxe)
xp (car (assoc 10 fd))
yp (cadr (assoc 10 fd))))
这将给出起始X和Y值xp yp
和实体列表yl
这将需要一个很好的工作来冲洗出来-大卫 嗯,我现在不想太容易,是吗眨眼:
谢谢你让我开始。
朗尼 在我看来,我倾向于使用VL来处理这个解决方案,因为它有助于实现更简洁的解决方案——我可能会这样处理。
我不想只给你解决方案,所以也许在你尝试后向下滚动。
< Scroll down to see solution >
(defun c:test ( / ss )
(vl-load-com)
;; © Lee Mac 2010
(if (setq ss (ssget "_:L" '((0 . "TEXT"))))
(
(lambda ( i / e l p h a )
(while (setq e (ssname ss (setq i (1+ i))))
(setq l (cons (entget e) l ))
)
(setq l
(vl-sort l
(function
(lambda ( a b )
(> (cadr (LM:GetTextInsertion a)) (cadr (LM:GetTextInsertion b)))
)
)
)
)
(setq p (LM:GetTextInsertion (car l)) h (* 1.5 (dxf 40 (car l))) a (/ (* 3 pi) 2.))
(
(lambda ( j )
(while (setq l (cdr l))
(LM:PutTextInsertion (car l) (polar p a (* (setq j (1+ j)) h)))
)
)
0
)
)
-1
)
)
(princ)
)
(defun dxf ( code lst ) (cdr (assoc code lst)))
(defun LM:GetTextInsertion ( eList )
;; © Lee Mac 2010
(dxf
(if (vl-every 'zerop
(mapcar 'dxf '(72 73) (list elist elist))
)
10 11
)
eList
)
)
(defun LM:PutTextInsertion ( eList point / code )
;; © Lee Mac 2010
(setq code
(if (vl-every 'zerop
(mapcar 'dxf '(72 73) (list elist elist))
)
10 11
)
)
(entupd
(cdr
(assoc -1
(entmod
(subst (cons code point) (assoc code elist) elist
)
)
)
)
)
) Lee发布了一个很好的解决方案,但由于我已经编写了它,我还是会与大家分享。我走了边界盒路线。
顺便说一句,李很酷。
<Scroll to see>
(defun c:ALT (/ foo lst)
;; Align TEXT objects
;; Alan J. Thomspon, 08.02.10
(vl-load-com)
(defun foo (o / a b)
(vla-getboundingbox o 'a 'b)
(vlax-safearray->list a)
)
(if (and (setq lst (vl-sort ((lambda (/ ss l)
(if (setq ss (ssget "_:L" '((0 . "TEXT"))))
(progn
(vlax-for x (setq ss (vla-get-activeselectionset
(cond (*AcadDoc*)
((setq *AcadDoc*
(vla-get-activedocument (vlax-get-acad-object))
)
)
)
)
)
;; (XYZ, height, object)
(setq l (cons (list (foo x) (vla-get-height x) x) l))
)
(vla-delete ss)
l
)
)
)
)
(function (lambda (a b) (> (cadar a) (cadar b))))
)
)
(not (initget 0 "Single Double"))
(setq *ALT:Space*
(cond ((getkword (strcat "\nSpecify spacing <"
(cond (*ALT:Space*)
((setq *ALT:Space* "Single"))
)
">: "
)
)
)
(*ALT:Space*)
)
)
)
((lambda (d m)
(foreach x (cdr lst)
(vla-move (caddr x)
(vlax-3d-point (car x))
(vlax-3d-point (polar (caar lst) (* pi 1.5) (setq d (+ d (* m (cadr x))))))
)
)
)
0.
(if (eq *ALT:Space* "Single")
1.5
3.
)
)
)
(princ)
) 干杯,伙计-你也发了一些不错的代码。我没想到会这么做
我认为你的代码的优点是,它将以与对齐无关的等距定位文本,而我的代码将等距定位插入点我想这取决于运算的预期结果。
太棒了我会试试这两个家伙。谢谢
在我今天早些时候计划这一例行活动时,我按照以下逻辑思考:
[列表]
[*]获取间距(单或双)并存储在变量“sp”中
[*]获取选择集
[*]将集合放入名为“list1”的待处理列表中
[*]根据最大的“Y”坐标值将列表处理到最小,并放入新列表“list2”
[*]获取新列表的第一个实体(即具有最大“Y”坐标值的实体),并将“Y”值存储到变量“ybase”中
[*]使用一个论坛进行FOREACH评估,该论坛将为列表中的每个实体提供新的Y值,其中每个值将增加指定间距的一个因子,然后放置在新列表“list3”中
[*]根据与“ybase”相关的“list3”将实体移动到新的“Y”位置
在不深入研究任何一个示例代码的情况下,就逻辑而言,这听起来是否正确? 避免VL路由所面临的问题是,您无法访问排序函数,因此必须实现自己的排序算法,最有可能的是冒泡排序。
vl排序函数在这方面更快,因为它很可能使用arx实现一种快速排序算法。
李
页:
[1]
2