PDA

View Full Version : How do I use the Active-X function AddMleader in Lisp


boesiii
2008-06-20, 04:43 PM
I am trying to write a routine that convert mtext and a leader into an mleader. The code I have works but it's not perfect because it doesn't format the text correctly. I thought I would be able to correct it by using the AddMleader function but I don't know the correct syntax



(defun rtd (a) (* (/ a pi) 180.0))

(defun dtr (a) (* (/ a 180.0) pi))

(defun c:mtext2ml (/)
(initerr)
(setq text_ob (entget (car (entsel "\Select Text Object: "))))
(setq text (cdr (assoc 1 text_ob)))
;(setq text_pt (cdr (assoc 10 text_ob)))
(print text)
(setq leader_ob (entget (car (entsel "\Select Leader Object: "))))
(setq len (length leader_ob))
(setq n 0)
(setq pt_list (list))
(repeat len
(setq object1 (car (nth n leader_ob)))
(if (= object1 10)
(progn
(setq pt_list (cons (cdr (nth n leader_ob)) pt_list))
);progn
);if
(setq n (1+ n))
);repeat
(print pt_list)
(setq pt_list_len (length pt_list))
(setq pt_list (reverse pt_list))
(setq leader_pt1 (car pt_list))
(setq leader_pt2 (nth (- pt_list_len 1) pt_list))
(print leader_pt1)
(print leader_pt2)
(setvar "osmode" 0)

(command "_mleader" leader_pt1 leader_pt2 text)



(reset)
(princ)
)
(princ)

irneb
2008-07-30, 09:20 AM
First off you need to obtain an ActiveX object for the Model Space. Then invoke the AddMLeader method passing the points list in a one-dimensional SafeArray format: (setq doc (vla-get-ActiveDocument (vlax-get-acad-object)));Get ActiveX object for Document
(setq ms (vla-get-ModelSpace doc));Get ActiveX object for Model Space
;; Assuming ptlst has 3D points
(setq ptarray (vlax-make-safearray vlax-vbDouble (cons 1 (* 3 (length ptlst)))))

(setq n 0)
(while (< n (length ptlst))
(setq pt (nth n ptlst))
(vlax-safearray-put-element ptarray (+ (* n 3) 1) (car pt))
(vlax-safearray-put-element ptarray (+ (* n 3) 2) (cadr pt))
(vlax-safearray-put-element ptarray (+ (* n 3) 3) (caddr pt))
(setq n (1+ n))
) ;_ end of while

(setq mlobj (vla-AddMLeader ms ptarray 0));Create and get the MLeader object
Not entirely sure why the extra "index" after the points array, but any integer gives the same result - so I just chode zero.

Thereafter you use the MLeader's methods & properties to add / modify the text:(vla-put-TextString mlobj text)

irneb
2008-07-30, 09:57 AM
I've tried changing the "position" of the text - to no avail. Other option is to select the new MLeader so the user can reposition the text(defun c:mtext2ml (/ doc ms mlobj pt pt_list ptarray n text_ob text leader_ob len object1)
;;(initerr)
(setq text_ob (entget (car (entsel "\Select Text Object: "))))
(setq text (cdr (assoc 1 text_ob)))
(setq leader_ob (entget (car (entsel "\Select Leader Object: "))))
(setq len (length leader_ob))
(setq n 0)
(setq pt_list (list))
(repeat len
(setq object1 (car (nth n leader_ob)))
(if (= object1 10)
(progn
(setq pt_list (cons (cdr (nth n leader_ob)) pt_list))
) ;progn
) ;if
(setq n (1+ n))
) ;repeat
(setq pt_list (reverse pt_list)) ;Reverse the list

(setq doc (vla-get-ActiveDocument (vlax-get-acad-object))) ;Get ActiveX object for Document
(setq ms (vla-get-ModelSpace doc)) ;Get ActiveX object for Model Space

(setq ptarray (vlax-make-safearray vlax-vbDouble (cons 1 (* 3 (length pt_list)))))

(setq n 0)
(while (< n (length pt_list))
(setq pt (nth n pt_list))
(vlax-safearray-put-element ptarray (+ (* n 3) 1) (car pt))
(vlax-safearray-put-element ptarray (+ (* n 3) 2) (cadr pt))
(vlax-safearray-put-element ptarray (+ (* n 3) 3) (caddr pt))
(setq n (1+ n))
) ;_ end of while

(setq mlobj (vla-AddMLeader ms ptarray 0)) ;Create the MLeader
(vla-put-TextString mlobj text) ;Set the text string
(vla-put-TextWidth mlobj (cdr (assoc 41 text_ob))) ;Set text's width
(vla-put-Layer mlobj (cdr (assoc 8 leader_ob))) ;Set mleader to the same layer

;; Delete old leader & mtext
(entdel (cdr (assoc -1 text_ob)))
(entdel (cdr (assoc -1 leader_ob)))

;; Select the new MLeader so the user can move the text
(sssetfirst nil (ssget "_l"))
(princ)
) ;_ end of defun

boesiii
2008-07-30, 07:21 PM
Thanks, I'll try it out

pheadpro
2008-12-05, 05:46 PM
We are doing the same thing replacing Leaders and Mtext with an Mleader object. I wrote this one to do the task. It sets a layer for the object based on the NCS 4.0 layer standards. I also have it testing the first object selected, if it is an Mleader the routine ends with a note stating object is already updated.
The problem I am having is how to import the Mleader style from our standards template if it is not already in the detail dwg. Does anyone know a way to do that?

(defun c:m2mld ()
;;capture the current layer setting. set or create the correct notes layer
(setq clyr (getvar "clayer"))
(setq lay1 (cdr (assoc 70 (tblsearch "layer" "G-ANNO-CALL-TEXT"))))
(if (= lay1 0)
(setq wsl "G-ANNO-CALL-TEXT")
(command "-layer" "m" "G-ANNO-CALL-TEXT" "c" "2" "" "")
)
(setvar "clayer" wsl)
;; select the leader and mtext entity to be replaced
(setq obj1 (car (entsel "\nSelect Leader: ")))
(setq obj2 (car (entsel "\nSelect Mtext: ")))
(setq et1 (entget obj1))
(setq et2 (entget obj2))
;;extract coordinates of the leader

;;test for Multileader. end if present
(if (/= (cdr (assoc 0 et1)) "MULTILEADER")
(progn
(setq cd01 (cdr
(assoc 10 et1)
)
)
(setq cd02
(cdr
(member
(assoc 10
(member (assoc 10 et1) et1)
)
et1
)
)
)
;;erase the previous set of entities
(progn
(command "erase" obj1 obj2 "")
(setq tx1 (cdr (assoc 1 et2)))
(setq cd011 cd01)
(setq cd022 (cdr(car cd02)))
;;create a Mleader to replace the previous set
(command "mleader" cd011 cd022 tx1)
)
)
(write-line "Entity is a Multileader object; nothing to do")
)
;;reset to previous layer
(setvar "clayer" clyr)
)

ccowgill
2008-12-05, 08:55 PM
Irneb, your routine is the closest I have been to a working version. I will try looking into text positioning. part of the problem is, for the last 2 points of the leader, you probably want to specify them as the DogLegLength, that will position the text a little better. Active-X is still somewhat out of my range of programming, I dont fully understand your code and what each part is doing. But I believe if you eliminate the last 2 leader points from the multileader creation, find the distance between the 2 and VLA-PUT-DogLegLength that value, it should fix up your issue with the text location.

Clear as mud?

irneb
2008-12-06, 01:18 PM
Will give your suggestion a try, thanks.Clear as mud?Or at least a murky cider (which is more to my taste :beer::beer::beer:)

To clear the murkiness (or the mud to taste): What I basically do is get the leader's text & vertices (convoluted I'm sure there's a better way). Then convert the list of points to a safearray matrix, since the vla-AddMLeader requires an array instead of a list (else it gives an error). Then for the rest, I think, there's enough comments to explain:mrgreen:.