Kyler 发表于 2022-7-5 16:41:32

LISP-自动标注ac

大家好,
 
我在一家玻璃公司工作,正在尝试编写一个AutoLISP命令,通过按供应商喜欢的格式标注带有孔和切口的玻璃面板尺寸,将我们的大部分工作自动化。
 
我会在这里附上一张照片,展示我到目前为止所做的事情。

 
左边的矩形显示了我想要的尺寸。
右边的矩形显示了我的LISP例程当前的功能。
我在编写逻辑以按我想要的方式对其进行尺寸标注时遇到了问题。
 
它应该遵循的规则是:
1) 尺寸字符串应制作到离孔最近的角落
2) 如果两个孔对齐,尺寸应穿过较近的孔
3) 如果两个维度到达同一个角,它们应以3”的间隔堆叠(通常为DIMBASELINE设置偏移)
4) 尺寸字符串应始终在其上方较大尺寸的后面3英寸(参见左上角的5英寸测量值)
 
然而,这些规则仅适用于“矩形”形状选项。在例程的最终版本中,我希望有一个易于扩展的规则列表,我可以修改和调整每个形状。
 
我在下面附上了一个测试图和LISP例程的当前版本。矩形尺寸标注规则的代码见第436-494行。
 
如果您能帮我解决这个问题,我们将不胜感激。
 
非常感谢。
 
图形文件:autodimtest。图纸
当前LISP:autoDim。lsp

BIGAL 发表于 2022-7-5 17:05:56

这是一大堆代码,不用花几个小时去想。我会在两个不同的层上进行两次尺寸标注,在构建形状时可能会更多。对于非常简单的形状矩形等,代码大小似乎过大,可能我看错了。
 
Ps喜欢形状块。

Kyler 发表于 2022-7-5 17:15:09

谢谢你的回复,比格尔。
 
你能详细说明你在两个不同的层面上标注尺寸的意思吗?
您是指图层特性管理器中定义的图层吗?
 
我对编程基本上是新手,所以我相信可以做很多简化。
 
目前,该程序的工作原理如下:
•分析多段线,必要时对其进行改造,以确保起点位于最左下角,并从那里顺时针走
•将每个顶点的坐标保存到变量A到H(在定义的所有形状中最多只有8个点)
•保存包围多段线最外顶点的边界框。这用于定义标注位置。我可以将其偏移3”,然后放置第一个dim,然后再次放置下一个dim,以允许dim堆叠
•将所有孔的坐标保存到列表中((x1 y1)(x2 y2).)然后可以按minX、minY等对列表进行排序。
•然后才开始根据此信息放置尺寸。大多数形状的基本尺寸规则已经包含在自定义函数drawDim中,遵循我制作的形状块中列出的规则。
 
我对孔的问题是,当尺寸标注到同一侧的不同角落时,堆叠必须重置。我认为我需要程序识别它之前的DIM和它之后的DIM,以便它可以动态地决定放置维度的堆叠级别,而不是在每次操作中严格地增加边界框大小。你可以在我的第一篇文章中看到,右边的矩形就是这样。
 
代码如此庞大有几个原因:
我选择为每个形状单独定义尺寸标注规则,其中有67个不同的形状,因为这将有助于我在未来对其进行扩展。
它如此长的另一个原因是,该命令还用作双重检查,以确保正确绘制形状。60%的代码是错误消息,检查某些角是否为正方形,边是否等长等。

BIGAL 发表于 2022-7-5 17:30:24

之后的最终输出是您已经生成的内容的变体,因此,堆叠的dim 12 15 20位于层DIM1上,尽管您在对象顶部执行dim 12,但位于层Dim2上。是的,它意味着一直翻转层(setvar“clayer”“dim2”)。这只是我,但写一些已经完成了根据规则,然后再次尝试重做它是非常困难的,这将意味着检查规则22,如果真的做规则22A。同样,您可能需要第三层DIM3,其dims始终可见。使用2个布局应该能够通过关闭视口中的正确图层来查看结果是否正确。

Kyler 发表于 2022-7-5 17:51:43

谢谢你的想法。
 
我想在不向绘图中添加任何附加层的情况下完成它。经过一些思考,我想出了一个只适用于我的代码解决方案。我会把它贴在这里给任何好奇或想看它的人。
 
我添加的代码:

(if (setq holes        (orgCoords holes "BL"))
(progn
        (foreach j holes
                (cond
                        ( (= (nearCoor j glassBorderPts) a)
                                (if (or(isInline j holes "y" "top")
                                        (not (isInline j holes "y" nil)))
                                        (setq orderedHoles (addHole j orderedHoles "bottom" a)))
                                (if (or(isInline j holes "x" "right")
                                        (not (isInline j holes "x" nil)))
                                        (setq orderedHoles (addHole j orderedHoles "left" a)))
                        )
                        ( (= (nearCoor j glassBorderPts) b)
                                (cond
                                        ( (isInline j holes "y" "top") (setq orderedHoles (addHole j orderedHoles "bottom" a)) )
                                        ( (not (isInline j holes "y" nil)) (setq orderedHoles (addHole j orderedHoles "top" b)) )
                                );cond
                                (if (or(isInline j holes "x" "right")
                                        (not (isInline j holes "x" nil)))
                                        (setq orderedHoles (addHole j orderedHoles "left" b)))
                        )
                        ( (= (nearCoor j glassBorderPts) c)
                                (cond
                                        ( (isInline j holes "y" "top") (setq orderedHoles (addHole j orderedHoles "bottom" d)) )
                                        ( (not (isInline j holes "y" nil)) (setq orderedHoles (addHole j orderedHoles "top" c)) )
                                );cond
                                (cond
                                        ( (isInline j holes "x" "right") (setq orderedHoles (addHole j orderedHoles "left" b)) )
                                        ( (not (isInline j holes "x" nil)) (setq orderedHoles (addHole j orderedHoles "right" c)) )
                                );cond
                        )
                        ( (= (nearCoor j glassBorderPts) d)
                                (if (or(isInline j holes "y" "top")
                                        (not (isInline j holes "y" nil)))
                                        (setq orderedHoles (addHole j orderedHoles "bottom" d)))
                                (cond
                                        ( (isInline j holes "x" "right") (setq orderedHoles (addHole j orderedHoles "left" a)) )
                                        ( (not (isInline j holes "x" nil)) (setq orderedHoles (addHole j orderedHoles "right" d)) )
                                );cond
                        )
                );cond
        );foreach
        (setq orderedHoles (orgCoords orderedHoles (list "bottom" a "LB")))
        (setq orderedHoles (orgCoords orderedHoles (list "bottom" d "RB")))
        (setq orderedHoles (orgCoords orderedHoles (list "left" a "BL")))
        (setq orderedHoles (orgCoords orderedHoles (list "left" b "TL")))
        (setq orderedHoles (orgCoords orderedHoles (list "top" b "LT")))
        (setq orderedHoles (orgCoords orderedHoles (list "top" c "RT")))
        (setq orderedHoles (orgCoords orderedHoles (list "right" c "TR")))
        (setq orderedHoles (orgCoords orderedHoles (list "right" d "BR")))
        (setq bounding (drawHoleDims orderedHoles bounding))
);progn
);if

 
isInline函数:

(defun isInline (pt pts axis dir / j ans flag)
;Checks if a point is inline with any point in a list of points,
;and if it is the furthest point inline point in a given direction
;pt                :        List - Coordinate pair (x y) for point to check
;pts                :        List - List of coordinate pairs for points to check against
;axis                :        String - Which axis to check for other points ("x" or "y")
;dir                :        String - Direction to check if point is the furthest ("left", "bottom", etc) pass nil to check for inline only
;Returns        :        T if holes are inline AND hole is furthest on specified direction, or if holes exist inline while dir=nil
;                                Nil if no holes are inline OR holes are inline but pt is not furthest in specified direction
(foreach j pts
        (cond
                ( (= j pt) )
                ( (and (= axis "x") (null dir) (equal (cadr pt) (cadr j) fuzz)) (setq ans T) )
                ( (and (= axis "y") (null dir) (equal (car pt) (car j) fuzz)) (setq ans T) )
                ( (and (= axis "x") (= dir "left")(equal (cadr pt) (cadr j) fuzz)               (< (car pt) (car j))) (setq ans T) )
                ( (and (= axis "x") (= dir "left")(equal (cadr pt) (cadr j) fuzz) (not (< (car pt) (car j)))) (setq flag T) )
                ( (and (= axis "x") (= dir "right") (equal (cadr pt) (cadr j) fuzz)               (> (car pt) (car j))) (setq ans T) )
                ( (and (= axis "x") (= dir "right") (equal (cadr pt) (cadr j) fuzz) (not (> (car pt) (car j)))) (setq flag T) )
                ( (and (= axis "y") (= dir "bottom")(equal (car pt) (car j) fuzz)           (< (cadr pt) (cadr j))) (setq ans T) )
                ( (and (= axis "y") (= dir "bottom")(equal (car pt) (car j) fuzz) (not (< (cadr pt) (cadr j)))) (setq flag T) )
                ( (and (= axis "y") (= dir "top") (equal (car pt) (car j) fuzz)           (> (cadr pt) (cadr j))) (setq ans T) )
                ( (and (= axis "y") (= dir "top") (equal (car pt) (car j) fuzz) (not (> (cadr pt) (cadr j)))) (setq flag T) )
        );cond
);foreach
(if flag (setq ans nil))
ans
);defun

 
drawHoleDims功能:

(defun drawHoleDims (holes ofst / finalBounding i j k l maxi)
;Draws dimensions for all coordinates in the ordered coordinate list passed
;holes                :        List - Ordered list of holes to dimension (list created with addHole command)
;ofst                :        List - Two sets of coordinates ((x1 y1) (x2 y2)) for bounding box to offset dimensions to
;Returns        :        List - New sets of coordinates ((x1 y1) (x2 y2)) for bounding box of final dimensions
(setq finalBounding ofst)
(foreach j holes
        (setq maxi 0)
        (foreach k (cdr j)
                (if (> (1- (vl-list-length k)) maxi) (setq maxi (1- (vl-list-length k))))
        );foreach
        (foreach k (cdr j)
                (setq i maxi)
                (foreach l (reverse (cdr k))
                        (setq i (1- i))
                        (drawDim l (car k) (if (/= i 0) (growbound ofst (car j) (* i ofstTYP)) ofst) (car j) nil)
                );foreach
        );foreach
        (setq finalBounding (growbound finalBounding (car j) (* maxi ofstTYP)))
);foreach
);defun

 
整个代码:autoDim。lsp
测试图纸:autodimtest。图纸
 
要使用,请运行命令并选择整个未标注的边界,包括形状块和所有孔。
 
它目前只支持矩形形状,但用我的设置方式为其余部分添加逻辑将是微不足道的。
 
如果有人在看这段代码时注意到我可以进行的任何优化,请告诉我!
页: [1]
查看完整版本: LISP-自动标注ac