chj20050606 发表于 2025-2-19 15:27:11

因新版xdrx-api安装影响其它插件应用,求助修改旧版插件

我用的是cad2024版本,安装新版的xdrx-api后,部分加载程序的lsp插件或者vlx插件就无法使用,总是显示为无效命令,但卸载了xdrx-api就又可以使用了,没办法只能卸载,但原来老版的靠xdrx-api的插件又用不了,旧版的xdrx-api又无法安装加载,求助修改一下原来的lsp文件能在cad2024下使用,最好是不需安装xdrx-api情况下可使用。

(defun c:xar (/ $get_point $remake_l ss curve dist tf num maxnum pnt pntl
                   vect xform vT1 vT2 mMat1 mMat2 mRot m0 mMat
                )
(defun $get_point (curve pnt dist / ptl pt dist1)
    (setq dist1 #xarray_dist)
    (while (setq pt (xdrx_curve_getpointatdist curve (+ dist dist1)))
      (setq dist1 (+ dist1 #xarray_dist)
            ptl (cons (trans pt 1 0) ptl)
      )
    )
    (reverse ptl)
)
(defun $remake_l (l num / ptl tf i)
    (setq ptl (reverse l))
    (if (< num (length l))
      (progn
      (setq ptl nil)
      (setq tf t)
      (setq i 0)
      (while tf
          (if (< i num)
            (setq ptl (cons (nth i l) ptl)
                  i (1+ i)
            )
            (setq tf nil)
          )
      )
      )
    )
    (reverse ptl)
)
(prompt "\n请选取要沿路径阵列的实体<退出>")
(if (and
      (setq ss (ssget))
      (setq curve (car (xdrx_entsel "\n点取一个路径(曲线)<退出>:" '
                                    ((0 . "*line,arc,circle,ellipse"))
                         )
                  )
      )
      )
    (progn
      (xdrx_begin)
      (xdrx_ucson)
      (if (not #xarray_dist)
      (setq #xarray_dist 100)
      )
      (redraw curve 3)
      (initget 6)
      (if (setq dist (getreal (strcat "\n阵列距离<" (rtos #xarray_dist 2 2)
                                    ">:"
                              )
                     )
          )
      (setq #xarray_dist dist)
      )
      (setq box (xdrx_entity_box ss)
            cen (xdrx_midp (car box) (caddr box))
            pnt (xdrx_curve_getClosestPoint curve cen)
            vec1 (xdrx_curve_getFirstDeriv curve pnt)
            pnt (trans pnt 1 0)
            baseDist (xdrx_curve_GetDistAtPoint curve pnt)
            pntl ($get_point curve pnt baseDist)
      )
      (initget 6)
      (setq maxnum (length pntl)
            tf t
      )
      (while tf
      (setq num (getint (strcat "\n输入数量(该路径上最大允许数量"
                                  (itoa maxnum) ")<" (itoa maxnum) ">:"
                        )
                  )
            num (if (not num)
                  maxnum
                  num
                  )
            tf (if (> num maxnum)
                   t
                   nil
               )
      )
      )
      (setq pntl ($remake_l pntl num)
            m0 (xdrx_matrix_identity)
            xForm (mapcar
                  '(lambda (x)
                     (setq vFDeriv (xdrx_curve_GetFirstDeriv curve (trans x 0 1))
                           mRot (xdrx_vector_rotateTo vec1 vFDeriv)
                           vT1 (mapcar '- (trans '(0 0 0) 0 1) (trans pnt 0 1))
                           vT2 (mapcar '- (trans x 0 1) (trans '(0 0 0) 0 1))
                           mMat1 (xdrx_matrix_setTranslation m0 vT1)
                           mMat2 (xdrx_matrix_setTranslation m0 vT2)
                           mMat (xdrx_matrix_product mRot mMat1)
                           mMat (xdrx_matrix_product mMat2 mMat)
                     )
                     )
                  pntl
                  )
      )
      (mapcar
      '(lambda (x)
         (xdrx_entity_transformedcopy ss x)
         )
      xForm
      )
      (redraw curve 4)
      (xdrx_ucsoff)
      (xdrx_end)
    )
)
(princ)
)

XDSoft 发表于 2025-2-19 18:06:44




用 deepseek 加上了注释


(defun c:tt ()
;; 主函数定义,定义了一个名为 `c:tt` 的命令

(if (and
      ;; 使用 `and` 函数来依次检查多个条件,只有所有条件都为真时,才会执行后续操作

      ;; 提示用户选择要阵列的对象,并将选择集赋值给 `ss`
      (setq ss (xdrx-ssget
                   (xdrx-string-multilanguage
                     "\n选择要阵列的对象<退出>:";; 中文提示
                     "\nSelect object to array<exit>:";; 英文提示
                   )
               )
      )

      ;; 提示用户选择一条路径曲线,并将选择的曲线实体赋值给 `curve`
      (setq curve (car (xdrx-entsel
                        (xdrx-string-multilanguage
                            "\n点取一个路径(曲线)<退出>:";; 中文提示
                            "\nClick a path (curve) <Exit>:";; 英文提示
                        )
                        '((0 . "*line,arc,circle,ellipse"));; 限制选择的实体类型为线、弧、圆、椭圆
                     )
             )
      )

      ;; 获取选择集 `ss` 的包围盒的中心点,并赋值给 `ptmid`
      (setq ptmid      (xdrx-getpropertyvalue (xdrx-entity-box ss) "9pt" 5)
            ;; 获取 `ptmid` 在曲线 `curve` 上的最近点,并赋值给 `closestpnt`
            closestpnt (xdrx-curve-getclosestpoint curve ptmid)
            ;; 获取曲线 `curve` 在 `closestpnt` 处的切向量,并赋值给 `firstderiv`
            firstderiv (xdrx-curve-getfirstderiv curve closestpnt))

      ;; 提示用户输入阵列的距离,并将输入的值赋值给 `dist`
      (setq dist (getreal (xdrx-string-multilanguage
                              "\n输入阵列距离<退出>:";; 中文提示
                              "\nEnter array distance <exit>:";; 英文提示
                            )
                   )
      )

      ;; 获取曲线上从 `closestpnt` 开始,每隔 `dist` 距离的点,并将这些点赋值给 `pts`
      (setq pts(xdrx-curve-getpointsatdist curve closestpnt dist)
            ;; 计算 `pts` 中点的数量,并赋值给 `nums`
            nums (length pts)
            ;; 设置一个标志变量 `tf`,初始值为 `t`(真)
            tf   t
      )

      ;; 使用 `while` 循环来确保用户输入的数量不超过路径上允许的最大数量
      (while tf
          (setq num (getint (xdrx-string-formatex
                              (xdrx-string-multilanguage
                              "\n输入数量(该路径上最大允许数量%d):<%d>";; 中文提示
                              "\nEnter quantity (maximum allowed quantity %d on this path): <%d>";; 英文提示
                              )
                              nums;; 最大允许数量
                              nums;; 默认值
                            )
                )
                ;; 如果用户没有输入数量,则使用默认值 `nums`
                num (if (not num)
                     nums
                     num
                     )
                ;; 如果用户输入的数量大于最大允许数量,则继续循环,否则退出循环
                tf(if (> num nums)
                     t
                     nil
                     )
          )
          t
      )
      )
    ;; 如果所有条件都满足,则执行以下操作
    (progn
      ;; 去掉 `pts` 中的第一个点(起点),因为阵列从第二个点开始
      (setq pts (cdr pts)
            ;; 计算源向量 `src_vec`,即 `closestpnt` 加上切向量 `firstderiv`
            src_vec (mapcar '+ closestpnt firstderiv)
            ;; 初始化计数器 `i` 为 0
            i 0
            ;; 将选择集 `ss` 转换为实体列表,并赋值给 `ents`
            ents (xdrx-pickset->ents ss))

      ;; 使用 `repeat` 循环来创建阵列
      (repeat num
      ;; 获取当前点的坐标,并赋值给 `pt`
      (setq pt      (nth i pts)
            ;; 递增计数器 `i`
            i       (1+ i)
            ;; 计算目标向量 `dst_vec`,即当前点 `pt` 加上该点的切向量
            dst_vec (mapcar '+ pt (xdrx-curve-getfirstderiv curve pt))
            ;; 复制实体列表 `ents`,并将复制的结果赋值给 `ss1`
            ss1   (xdrx-entity-copy ents)
      )
      ;; 将复制的实体 `ss1` 从源向量 `src_vec` 对齐到目标向量 `dst_vec`
      (xdrx-entity-align
          ss1 closestpnt src_vec pt dst_vec)
      )
    )
)
;; 结束 `if` 语句

;; 静默退出,不返回任何值
(princ)
)


下面是deepseek的深度思考,已学习了XDRX API

======================================


好的,我现在需要分析用户提供的LISP程序`c:tt`的逻辑。这个程序看起来是一个AutoCAD的定制命令,用于沿着选定的路径曲线阵列对象。用户之前已经得到了代码的详细注释,现在需要我解释代码的整体逻辑。
首先,我要通读整个代码,理解每个部分的作用。用户可能希望了解程序是如何工作的,包括用户交互、几何计算和实体操作的具体流程。我需要分解代码的各个步骤,并解释它们如何协同工作来实现最终功能。
从代码结构来看,主要使用`if`和`and`来组合多个条件检查,确保所有必要的输入和计算都正确完成。程序大致分为以下几个部分:
1. **用户输入阶段**:- 选择要阵列的对象(`xdrx-ssget`)- 选择路径曲线(`xdrx-entsel`)- 输入阵列间距(`getreal`)- 输入阵列数量(`getint`)
2. **几何计算阶段**:- 计算选择集的中心点(`xdrx-getpropertyvalue`)- 找到曲线上离中心点最近的点(`xdrx-curve-getclosestpoint`)- 计算该点的切向量(`xdrx-curve-getfirstderiv`)- 沿曲线按指定间距生成点列(`xdrx-curve-getpointsatdist`)
3. **输入验证与处理**:- 确保用户输入的数量不超过曲线上可容纳的最大点数- 处理默认值(如果用户直接回车)
4. **阵列操作阶段**:- 复制原始对象(`xdrx-entity-copy`)- 对齐复制的对象到路径上的每个目标点(`xdrx-entity-align`)
接下来,我需要验证这些步骤是否在代码中正确实现,并解释关键函数和逻辑判断的作用。例如,`xdrx-string-multilanguage`用于多语言提示,`while`循环确保用户输入合理的数量。
同时,需要关注可能的边界情况,例如当用户输入的间距过大导致生成的点数不足时,程序如何处理。代码中的`while tf`循环会强制用户重新输入数量,直到不超过最大允许值。
另外,要注意到`xdrx-entity-align`函数的作用,它根据源点和目标点的位置及方向向量进行对齐,确保复制后的对象沿着路径正确旋转和定位。
在解释过程中,可能会遇到一些需要进一步验证的XDRX-API函数,例如`xdrx-curve-getpointsatdist`的具体行为。假设这些函数按预期工作,返回沿曲线按间距分布的点列。
最后,总结整个程序的逻辑流程,强调用户如何通过交互步骤完成路径阵列,并指出代码中关键的技术点,如几何变换和输入验证。

以下是 c:tt 命令的代码逻辑分析,按执行流程分解为关键步骤:1. 用户交互阶段(1) 选择要阵列的对象
[*]函数:xdrx-ssget
[*]功能:
[*]弹出多语言提示(中英文),要求用户选择要阵列的对象。
[*]返回用户选择的对象集合(选择集 ss)。

[*]失败处理:若用户未选择对象,直接退出命令。
(2) 选择路径曲线
[*]函数:xdrx-entsel
[*]功能:
[*]提示用户选择一条路径曲线(支持直线、圆弧、圆、椭圆)。
[*]通过过滤器 '((0 . "*line,arc,circle,ellipse")) 限制可选的实体类型。
[*]返回用户选择的曲线实体 curve。

[*]失败处理:若用户未选择有效曲线,退出命令。
(3) 输入阵列间距
[*]函数:getreal
[*]功能:
[*]提示用户输入阵列间距(相邻对象间的距离)。
[*]将输入值赋给 dist。

[*]失败处理:若用户未输入有效数值,退出命令。
2. 几何计算阶段(1) 计算选择集的中心点
[*]函数:xdrx-getpropertyvalue
[*]参数:(xdrx-entity-box ss) "9pt" 5
[*]xdrx-entity-box:获取选择集 ss 的包围盒。
[*]"9pt" 5:提取包围盒的几何中心点 ptmid。

(2) 查找曲线上最近点
[*]函数:xdrx-curve-getclosestpoint
[*]参数:curve ptmid
[*]功能:计算路径曲线 curve 上离 ptmid 最近的点 closestpnt。
(3) 计算切向量
[*]函数:xdrx-curve-getfirstderiv
[*]参数:curve closestpnt
[*]功能:获取曲线在 closestpnt 处的切向量 firstderiv,用于后续对齐操作。
(4) 生成沿曲线的点列
[*]函数:xdrx-curve-getpointsatdist
[*]参数:curve closestpnt dist
[*]功能:从 closestpnt 开始,沿曲线按间距 dist 生成一系列点,存储为 pts。
[*]关键值:nums (length pts) 表示路径上可容纳的最大对象数量。
3. 输入验证与处理(1) 用户输入数量
[*]函数:getint
[*]逻辑:
[*]提示用户输入阵列数量,格式化为 "\n输入数量(最大%d):<%d>",动态插入 nums。
[*]若用户直接回车(空输入),默认使用 nums。
[*]若输入值 num 超过 nums,循环提示重新输入,直到合法。

4. 阵列操作阶段(1) 准备参数
[*]操作:(setq pts (cdr pts) ...)

[*]移除 pts 的第一个点(起始点 closestpnt,因为原始对象已在此位置)。
[*]计算源对齐向量 src_vec = closestpnt + firstderiv(原始对象的对齐方向)。
[*]将选择集 ss 转换为实体列表 ents,便于复制。
(2) 循环复制与对齐
[*]循环:(repeat num ...)

[*]复制对象:(xdrx-entity-copy ents) 创建副本 ss1。
[*]目标点计算:
[*]从 pts 中按顺序取点 pt。
[*]计算目标点的切向量 dst_vec = pt + (切向量)。

[*]对齐操作:(xdrx-entity-align ss1 closestpnt src_vec pt dst_vec)
[*]将复制的对象从 closestpnt 对齐到 pt。
[*]根据源向量 src_vec 和目标向量 dst_vec 旋转/平移对象,保持沿路径方向。

5. 结束处理
[*]静默退出:(princ) 避免在AutoCAD命令行输出冗余信息。
关键逻辑总结
[*]路径对齐的核心:
通过 xdrx-entity-align 实现动态对齐,使每个复制的对象沿路径的切线方向正确旋转,而不仅仅是平移。
[*]输入验证机制:
while 循环确保用户输入的数量不超过路径容量,避免无效操作。
[*]几何计算依赖:
所有几何操作(如最近点、切向量、等距点)均依赖 xdrx- 系列函数,需确保XDRX API已正确加载。
[*]多语言支持:
使用 xdrx-string-multilanguage 实现中英文提示,增强国际化兼容性。
示例场景假设用户选择了一个圆作为路径曲线,输入间距为 10,数量为 5:
[*]程序会从原始对象中心点开始,沿圆周每隔 10 单位生成一个点。
[*]复制原始对象,并依次对齐到这些点,同时根据圆周切线方向旋转对象。
[*]最终生成 5 个沿圆周均匀分布且方向正确的对象副本。
此逻辑适用于任意开放或闭合的路径曲线(如多段线、样条线等),通用性较强。

chj20050606 发表于 2025-2-22 17:20:43

本帖最后由 chj20050606 于 2025-2-22 17:22 编辑

还是不行啊

C:\Users\Administrator\AppData\Local\Temp\企业微信截图_17402157938204.png

XDSoft 发表于 2025-2-24 13:03:24

chj20050606 发表于 2025-2-22 17:20
还是不行啊

下载安装XDRX API 或者晓东工具箱,最新版

chj20050606 发表于 2025-2-26 17:31:15

安装了最新版晓东工具箱后,好多自己加载的lsp就用不了了,显示无效命令。连最简单的都用不了,例如:
(DEFUN C:sd()
(COMMAND "osnap" "ENDP,INT,ext,appint,mid,cen,qua,nod,nea")
(princ))

XDSoft 发表于 2025-2-26 19:06:42

chj20050606 发表于 2025-2-26 17:31
安装了最新版晓东工具箱后,好多自己加载的lsp就用不了了,显示无效命令。连最简单的都用不了,例如:
(DEF ...

安装晓东工具箱后:
1. 上面的插件,是否正常了?
2. 晓东工具箱的插件是否正常使用?

你贴的 sd 命令,我拷贝粘贴,加载正常.
你确保已经加载了 sd 的LSP代码了吗?

chj20050606 发表于 2025-2-27 22:37:36

我是把lsp插件加载到cad的启动组里面的,默认应该是cad启动后自动加载的。安装晓东工具箱后,一部分启动组的插件可以使用,一部分显示为无效命令。可能有两种情况,一种是晓东工具箱与插件冲突,一种就是晓东工具箱可能影响插件的加载,造成部分插件虽然在自动组里面,但实际上没有自动加载上。
目前上面的问题还没能解决,我今天还试过了。

chj20050606 发表于 2025-2-27 22:41:48

我已经安装了晓东工具箱,由于影响插件使用,我在文件搜索路径中将工具箱的搜索路径删除掉,插件就可以正常使用,如果将工具箱的路径再添加上的话,插件就又不能使用了,就是这个情况。

chj20050606 发表于 2025-3-10 15:51:34

由于非常迫切需要该功能,cad2024自带的沿路径阵列功能非常不好用,但是晓东工具箱安装又影响其它功能。可否拜托高手帮忙把程序修改为在不安装晓东工具箱情况下可直接运行,相当于把使用到的函数库文件直接放到程序中去,谢谢啦

XDSoft 发表于 2025-3-10 16:03:30

chj20050606 发表于 2025-3-10 15:51
由于非常迫切需要该功能,cad2024自带的沿路径阵列功能非常不好用,但是晓东工具箱安装又影响其它功能。可 ...
你安装完晓东工具箱,然后在手动添加下你插件的路径
或者你打开工具箱安装目录里面的 xdrx.rx 文件,编辑,把你要加载的LISP 带路径和LSP文件写到XDRX.RX里面,会自动加载他们的
编辑xdrx.rx文件
输入:比如
d:\\abc\\a.lsp
.......
保存

chj20050606 发表于 2025-3-11 00:58:07

努力了,修改了xdrx.rx文件并保存,并不会主动加载我的lsp文件,同时启动组里面的lsp文件也失效了,如果再次手动加载lsp文件,还是有效的。说明晓东工具箱确实影响自动组里面的lsp文件的加载。取消晓东工具箱,启动组里面的lsp文件是自动有效的。也不知道是否是xdrx.rx文件修改的不对。
文件路径的两种个格式修改也都是无效的。
已经尽力了,真的没办法解决这个问题。

XDSoft 发表于 2025-3-11 19:50:13

chj20050606 发表于 2025-3-11 00:58
努力了,修改了xdrx.rx文件并保存,并不会主动加载我的lsp文件,同时启动组里面的lsp文件也失效了,如果再 ...

你把这几个LISP,压缩打包,传上来,我看看

chj20050606 发表于 2025-3-11 23:21:35

lsp功能都很简单,都是根据自己的习惯搞得非常简单功能的东西。

chj20050606 发表于 2025-3-17 10:57:03

请教XDsoft管理员,有办法解决吗?迫切需要啊。

XDSoft 发表于 2025-3-17 19:58:36

chj20050606 发表于 2025-3-17 10:57
请教XDsoft管理员,有办法解决吗?迫切需要啊。


现在附件的xdrx.lsp 覆盖到 工具箱的 sys目录,
然后用上面的设置 xdrx.rx的方式,你看看



页: [1] 2
查看完整版本: 因新版xdrx-api安装影响其它插件应用,求助修改旧版插件