jes_g 发表于 2022-7-5 15:37:03

查找最近的多段线,创建

大家好,
 
我正在尝试编写一个LISP例程,该例程将完成以下任务:
1、选择图纸上的块参照
2.从该块参照中查找最近的多段线和该多段线上的最近点
3.在该点上创建顶点,并将该点的坐标保存到变量中以供进一步使用
4.从该块参考中提取对象数据,如SerialNo(请参阅随附的屏幕截图)
5.每个块参考的回路
6.将先前保存的点坐标及其对应的序列号导出为txt或csv,如下所示:
X_coord,Y_coord,序列号
 
E、 g.85.4535、18.7903、09I4E5Q2104022719
或85.4535、18.7903、09I4E5Q2104022311、09I4E5Q2104022719(如果其具有多个块参考)
 
输出文件被解释为在该特定点上具有负载的电线。
 
以下是我迄今为止发现/借用的有帮助的内容:
用于在此线程上创建DeviceG提供的顶点程序
 
;; Design by Gabo CALOS DE VIT from CORDOBA ARGENTINA
;;;    Copyleft 1995-2018 by Gabriel Calos De Vit
;; DEVITG@GMAIL.COM   

; Hecho porGabo CALOS DE VIT de CORDOBA ARGENTINA
;;;    Copyleft 1995-2018 por Gabriel Calos De Vit
;; DEVITG@GMAIL.COM
; no error check.
;; no nothing

(vl-load-com)
(DEFUN C:EXAMPLE_ADDVERTEX( /
ACADOBJ
BLK-REF-XYZ
BLK-REFERENCE
DOC
LSTPOINT
MODELSPACE
NEWVERTEX
PARAM-AT-CLOSEST-POINT
PLINE
PLINE-OBJ
POINT-AT-PARAM
VERTEX-POINT


                            )

(SETQ ACADOBJ (VLAX-GET-ACAD-OBJECT))
(SETQ DOC (VLA-GET-ACTIVEDOCUMENT ACADOBJ))
(SETQ MODELSPACE (VLA-GET-MODELSPACE DOC))

(SETQ PLINE (ENTSEL "\nSelect Polyline: "))
(SETQ PLINE-OBJ (VLAX-ENAME->VLA-OBJECT (CAR PLINE)))

(SETQ BLK-REFERENCE (CAR (ENTSEL "\Select the block-reference")))
(SETQ BLK-REF-XYZ (CDR (ASSOC 10 (ENTGET BLK-REFERENCE))))
;;;(VL-CMDF "POINT" BLK-REF-XYZ "")
(SETQ LSTPOINT (VLAX-CURVE-GETCLOSESTPOINTTO PLINE-OBJ BLK-REF-XYZ))

(SETQ PARAM-AT-CLOSEST-POINT (VLAX-CURVE-GETPARAMATPOINT PLINE-OBJ LSTPOINT))
(SETQ POINT-AT-PARAM (VLAX-CURVE-GETPOINTATPARAM PLINE-OBJ PARAM-AT-CLOSEST-POINT))
(SETQ VERTEX-POINT (LIST (CAR POINT-AT-PARAM) (CADR POINT-AT-PARAM)))
;;;(VL-CMDF "POINT" VERTEX-POINT "")

(SETQ NEWVERTEX (VLAX-MAKE-SAFEARRAY VLAX-VBDOUBLE '(0 . 1)))
(VLAX-SAFEARRAY-FILL NEWVERTEX VERTEX-POINT)

(VLA-ADDVERTEX PLINE-OBJ (1+ (FIX PARAM-AT-CLOSEST-POINT)) NEWVERTEX)
(VLA-UPDATE PLINE-OBJ)
)
 
它工作得很好,但现在需要修改以在循环中工作
 
对于提取对象数据,BlackBox在此线程上提供的答案可能会有所帮助
 
随附样品图
 
谢谢你的帮助
非常感谢。
 
当做
Jes G公司
 
 
示例图。图纸

abra-CAD-abra 发表于 2022-7-5 15:51:24

jes\u g,
 
这是我周五下午的尝试。
 
假设您的数据(序列号?)包含在每个块的属性中;
提取第一个属性值(序列号);
 
1选择多段线;然后
2选择块。
 
将(在选定的多段线上)在每个块的最近点处放置一个点;和
数据将保存到CSV文件中
 

(defun C:ODATA (/ pl s fn opn i e de dp )
(vl-load-com)

(setvar 'pdmode 3)


   (while
(progn
(setvar 'errno 0)
(setq pl
(car (entsel "\nSelect Polyline: ")
) ;_ end of car
) ;_ end of setq
(cond
    ((= 7 (getvar 'errno))
   (princ "\nMissed, Please Try Again.")
    )
    ((/= "LWPOLYLINE" (cdr (assoc 0 (entget pl))))
   (princ
       "\nThe Selected Entity is not a LWPOLYLINE."
   ) ;_ end of princ
    )
) ;_ end of cond
) ;_ end of progn
   ) ;_ end of while

(prompt "\nSelect **Attributed** Blocks to Process: ")

(if (and (setq s (ssget "_:L" '((0 . "INSERT") (66 . 1))))
   (setq fn (getfiled "Save Block Data to CSV File"
      (vl-filename-base (getvar 'dwgname))
      "csv"
      1
   ) ;_ end of getfiled
   ) ;_ end of setq
   (setq opn (open fn "w"))
   ) ;_ end of and

   (progn
   (write-line
(strcat
"SERIAL NUMBER (ATTRIBUTE)"
","
"ELEC LINE VERTEX EASTING"
","
"ELEC LINE VERTEX NORTHING"
","
"BLOCK INSERTION EASTING"
","
"BLOCK INSERTION NORTHING"
    ) ;_ end of strcat
    opn
) ;_ end of write-line

   (close opn)
   (setq opn (open fn "a"))
   (repeat (setq i (sslength s))
(setq e (vlax-ename->vla-object (ssname s (setq i (1- i)))))
(setq
de (vlax-get e 'insertionpoint)
dp (vlax-curve-getclosestpointto pl de)
) ;_ end of setq
(vl-cmdf "_.point" dp "")
(write-line
(strcat
    (vla-get-textstring (car (vlax-invoke e 'getattributes)))
    ","
    (rtos (car dp) 2 4)
    ","
    (rtos (cadr dp) 2 4)
    ","
    (rtos (car de) 2 4)
    ","
    (rtos (cadr de) 2 4)
) ;_ end of strcat
opn
) ;_ end of write-line
   ) ;_ end of repeat
   ) ;_ end of progn
) ;_ end of if
(close opn)
(princ)
) ;_ end of defun

 
 
我不是专家,但希望这能让你更接近你想要的解决方案。
 
干杯
奥达塔。lsp

jes_g 发表于 2022-7-5 15:54:36

 
谢谢你的回复。我运行这段代码,当我尝试选择块参照时,它们不会被选中。非常感谢。

ronjonp 发表于 2022-7-5 16:03:03

这里有一个快速的开始。我已经发表了评论,所以你可以编辑代码,以完全满足你的需要。
(defun c:foo (/ _writefile d od out p p2 s s1 tmp x)
;; RJP - 2.2.2018
(defun _writefile (file l / fo)
   (cond ((and (eq 'str (type file)) (setq fo (open file "w")))
   (foreach x l (write-line (vl-princ-to-string x) fo))
   (close fo)
   file
)
   )
)
(if (= 'exrxsubr (type ade_odgettables))
   (if        (and ;; All the meters
   (setq s (ssget "_x" '((0 . "insert") (2 . "tempmeter"))))
   ;; All the lwpolys on layer *Phase
   (setq s1 (ssget "_x" '((0 . "lwpolyline,line") (8 . "*phase"))))
   ;; Convert block to list of enames
   (setq s (mapcar 'cadr (ssnamex s)))
   ;; Convert lwpolys to list of enames
   (setq s1 (mapcar 'cadr (ssnamex s1)))
)
   ;; For each meter
   (progn
(foreach b s
;; Get meter basepoint
(setq p (cdr (assoc 10 (entget b))))
;; List of '((<closepoint> <distance> <ename>)...)
(setq        d
       (mapcar
           '(lambda (x) (list (setq p2 (vlax-curve-getclosestpointto x p)) (distance p p2) x))
           s1
       )
)
;; Sort by closest distance and retrieve first item
(setq d (car (vl-sort d '(lambda (r j) (< (cadr r) (cadr j))))))
;; Get serial number
(setq od (ade_odgetfield b (car (ade_odgettables b)) "SerialNo" 0))
;; If the serial number is blankchange to "OHNOES!!!!!NoSerial!"
(and (= "" od) (setq od "OHNOES!!!!!NoSerial!"))
;; Create point on closest pline
(entmakex (list '(0 . "point") '(8 . "MeterClosePoint") (cons 10 (car d))))
;; Create line for visual check
(entmakex (list '(0 . "line") '(8 . "Check") (cons 10 p) (cons 11 (car d))))
;; Create a vertex if it passes checks
(and (= "LWPOLYLINE" (cdr (assoc 0 (entget (setq o (caddr d))))))
       (vlax-write-enabled-p (setq o (vlax-ename->vla-object o)))
       (setq i (vlax-curve-getparamatpoint o (setq p2 (car d))))
       (or (= 0 (fix i)) (/= 0 (rem (fix i) i)))
       (vlax-invoke o 'addvertex (1+ (fix i)) (list (car p2) (cadr p2)))
)
;; Gather results
(if (setq tmp (assoc (car d) out))
    ;; Point in list exists so append entry
    (setq out (subst (append tmp (list (strcat "," od))) tmp out))
    ;; New point just add item
    (setq out (cons (list (car d) od) out))
)
)
;; Write file to current directory
(_writefile
(strcat (getvar 'dwgprefix) "MeterStuff.csv")
(mapcar
    '(lambda (x)
       (apply
       'strcat
       (append (mapcar '(lambda (y) (strcat (vl-princ-to-string y) ",")) (car x)) (cdr x))
       )
   )
    out
)
)
   )
   )
   (print "Civil3D needed for this code...")
)
(princ)
)

jes_g 发表于 2022-7-5 16:12:44

 
哇!这看起来很完美!谢谢
我唯一需要的是在多段线上创建新的顶点,其中最近的点如图所示。您建议如何修改?

 
非常感谢。非常感谢你的帮助

ronjonp 发表于 2022-7-5 16:21:48

我更新了代码。。试试看。记得给服务员小费。

jes_g 发表于 2022-7-5 16:34:43

 
最后一件事。希望你没有厌倦
如何在图片上显示的多段线上创建新顶点?

 
谢谢

ronjonp 发表于 2022-7-5 16:39:46

查看您的个人信息。。我已经解决了这个问题。
页: [1]
查看完整版本: 查找最近的多段线,创建