Author Topic: Aligning multileaders  (Read 18666 times)

0 Members and 1 Guest are viewing this topic.

Chris

  • Swamp Rat
  • Posts: 548
Aligning multileaders
« on: September 05, 2008, 07:43:23 AM »
Ok, I have been somewhat frustrated with AutoCAD's inability to properly align multileaders.  It is the only thing I believe is holding up our office from using them instead of our current standard Qleader.  Currently the MLEADERALIGN command moves the text to line up, disregarding the length of the landing.  I am trying to develop a program that will modify the length of the landing, so the leader does not change angle or locations, the text moves, and the tail gets longer or shorter as necessary. here is what I have so far, it doesnt do anything, maybe someone else can assist with it.
Code: [Select]
(defun c:multileaderalign (/        ss    ss2
   ent2        entdata2    textlocx
   ssno        count    mleader
   entdata1    textlocy1   textlocz1
   leglength   textlocx2   textlocx3
   textlocy3   textlocz3   extail
   proptail
  )
  (prompt "\nSelect multileaders:\n")
  (setq ss (ssget '((0 . "MULTILEADER"))))
  (if (/= ss nil)
    (progn
      (prompt "\nSelect multileader to align to:\n")
      (setq ss2 (ssget ":S" '((0 . "MULTILEADER"))))
      (if (/= ss2 nil)
(progn
  (setq ent2   (ssname ss2 0)
entdata2  (entget ent2)
textlocx  (car (cdr (assoc 12 entdata2)))
textlocx2 (car (cdr (assoc 10 entdata2)))
leglength (cdr (assoc 41 (reverse entdata2)))
ssno   (sslength ss)
count   0
  ) ;_ end of setq
  (while (< count ssno)
    (setq mleader   (ssname ss count)
  entdata1  (entget mleader)
  textlocx1 (car (cdr (assoc 12 entdata1)))
  textlocy1 (cadr (cdr (assoc 12 entdata1)))
  textlocz1 (caddr (cdr (assoc 12 entdata1)))
  textlocx3 (car (cdr (assoc 10 entdata1)))
  textlocy3 (cadr (cdr (assoc 10 entdata1)))
  textlocz3 (caddr (cdr (assoc 10 entdata1)))
  entdata1  (subst
      (assoc 12 entdata1)
      (cons 12 (list textlocx textlocy1 textlocz1))
      entdata1
    ) ;_ end of subst
  )
    (entmod Entdata1)
    (setq
   
  entdata1  (subst
      (assoc 10 entdata1)
      (cons 10 (list textlocx2 textlocy3 textlocz3))
      entdata1
    ) ;_ end of subst
  )
    (entmod Entdata1)
    (setq
  extail    (cdr (assoc 40 (reverse entdata1)))
  proptail  (+ extail (- textlocx textlocx1))
  entdata1  (subst (assoc 40 (reverse entdata1))
   (cons 40 proptail)
   entdata1
    ) ;_ end of subst
  )
    (entmod Entdata1)
    (setq
  entdata1  (subst (assoc 41 (reverse entdata1))
   (cons 41 proptail)
   entdata1
    ) ;_ end of subst
    ) ;_ end of setq
    (entmod Entdata1)
    (entupd mleader)
    (setq count (1+ count))
  ) ;_ end of while
) ;_ end of progn
      ) ;_ end of if
    ) ;_ end of progn
  ) ;_ end of if
) ;_ end of defun



Christopher T. Cowgill, P.E.
AEC Collection 2020 (C3D)
Win 10

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Aligning multileaders
« Reply #1 on: September 05, 2008, 09:08:42 AM »
I only have ACAD2006 so no MultiLeaders.
Looks like you want to pick one leader text & align the selection set of leaders to that text x-axis position
and adjust all the leader tails. Is that it?
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

Chris

  • Swamp Rat
  • Posts: 548
Re: Aligning multileaders
« Reply #2 on: September 05, 2008, 09:13:17 AM »
that's exactly it, you would think that the entmod and entupd would change the data, but when i run an entget on the entity after the fact, the data has not changed.  Does anyone know if entmod does not work on multileaders?
Christopher T. Cowgill, P.E.
AEC Collection 2020 (C3D)
Win 10

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Aligning multileaders
« Reply #3 on: September 05, 2008, 10:45:30 AM »
You might be fighting a reactor.
Why don't you try to use the MOVE command to move the text as needed & see if the reactor fixes the
leader line for you?
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

ronjonp

  • Needs a day job
  • Posts: 7529
Re: Aligning multileaders
« Reply #4 on: September 05, 2008, 10:49:58 AM »
This could definitely be improved upon...but I think it does what you want:

Code: [Select]
(defun c:alignlandings (/ ss al alxpt el lp cp1 cp2)
  (if (and (setq ss (ssget '((0 . "MULTILEADER"))));;gets leader selection set
   (setq al (car (entsel "\nSelect leader to align to: ")));;gets leader to align to ename
   (setq alxpt (cdr (assoc 10 (entget al))));;(cdr strips the first item 10 and just returns the landing endpoint
      )
    (foreach ml (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss)));;convert the selection set to a list of enames
      (setq el (entget ml);;converts ename to entity list
    lp (cdr (assoc 10 el));;(cdr strips the first item 10 and just returns the landing endpoint
    cp1 (polar lp 5.497 0.1);;bottom right diagonal point from landing point
    cp2 (polar lp 2.356 0.1);;upper left diagonal point from landing point
      )
      (command ".stretch" "box" cp1 cp2 "" lp alxpt);;stretch using box selection from lp to alxpt
    )
  )
  (princ)
)
« Last Edit: September 05, 2008, 11:14:44 AM by ronjonp »

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

Chris

  • Swamp Rat
  • Posts: 548
Re: Aligning multileaders
« Reply #5 on: September 05, 2008, 11:06:12 AM »
This could definitely be improved upon...but I think it does what you want:

Code: [Select]
(defun c:alignlandings (/ ss al alxpt el lp)
  (if (and (setq ss (ssget '((0 . "MULTILEADER"))))
   (setq al (car (entsel "\nSelect leader to align to: ")))
   (setq alxpt (cdr (assoc 10 (entget al))))
      )
    (foreach ml (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss)))
      (setq el (entget ml)
    lp (cdr (assoc 10 el))
    cp1 (polar lp 5.497 0.1)
    cp2 (polar lp 2.356 0.1)
      )
      (command ".stretch" "box" cp1 cp2 "" lp alxpt)
    )
  )
  (princ)
)
I think that will work, I'm not that familar with the mapcar and entsel commands, could you possibly explain what each part of the program is doing so I can learn from it and use this in the future?
here is my understanding:
select all the multileaders you wish to align
select the multileader you want to align to (entsel selects a single object, provides the object itself, and the selection point which is not necessary, hence the reason for the car)
grabs the point location information from the end of the tail
I'm guessing the foreach cycles through the selection set looking at each item
lp gets the current value of the end of the tail
cp1 and cp2 are your selection windows for the stretch command
and the stretch command, selects the objects, stretching the objects from lp to alxpt.

correct?
are there any limitations that you are aware of?
Christopher T. Cowgill, P.E.
AEC Collection 2020 (C3D)
Win 10

ronjonp

  • Needs a day job
  • Posts: 7529
Re: Aligning multileaders
« Reply #6 on: September 05, 2008, 11:16:56 AM »
I commented the code above. You're take on what the routine does was pretty close :).

As far as limitations...I don't know other than it will not stretch the mleader if the stretched landing space is too small.

Ron

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

Chris

  • Swamp Rat
  • Posts: 548
Re: Aligning multileaders
« Reply #7 on: September 05, 2008, 11:20:08 AM »
well I'm sure if I find any limitations, I will be back to help try to solve them.
as a small side note, do you have any clue how to change the default prompt on ssget from "Select objects:"  with dynamic input on, it would be nice if you could see "Select multileaders:" instead
Christopher T. Cowgill, P.E.
AEC Collection 2020 (C3D)
Win 10

Chris

  • Swamp Rat
  • Posts: 548
Re: Aligning multileaders
« Reply #8 on: September 05, 2008, 11:29:35 AM »
I have found a limitation
if the leaders are coming from the opposite direction, the end of the tail lines up with the insert of the text.

this would be alleviated by using the 12 dxf instead of the 10 dxf.

there is another limitation, that I find difficult to describe, but I could see it happening.  A pictures worth a thousand words, so take a look.

I cant get "here to" to align with "testing this to see if it works"

I think it may have something to do with the crossing window, the points would need to be flopped in this situation for it to select it, correct?
« Last Edit: September 05, 2008, 11:35:58 AM by Chris »
Christopher T. Cowgill, P.E.
AEC Collection 2020 (C3D)
Win 10

ronjonp

  • Needs a day job
  • Posts: 7529
Re: Aligning multileaders
« Reply #9 on: September 05, 2008, 11:36:11 AM »
If you post a drawing with possible scenarios, that would help. I have never used mleaders before so I'm having trouble picturing problems.

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

Chris

  • Swamp Rat
  • Posts: 548
Re: Aligning multileaders
« Reply #10 on: September 05, 2008, 11:40:02 AM »
If you post a drawing with possible scenarios, that would help. I have never used mleaders before so I'm having trouble picturing problems.

I think these would be the 4 major scenarios I would want to account for.
Christopher T. Cowgill, P.E.
AEC Collection 2020 (C3D)
Win 10

ronjonp

  • Needs a day job
  • Posts: 7529
Re: Aligning multileaders
« Reply #11 on: September 05, 2008, 11:48:17 AM »
Sorry..I'm still not getting it  :? So what is the desired alignment point for each scenario?

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Aligning multileaders
« Reply #12 on: September 05, 2008, 11:50:49 AM »
I suspect that you will need to use the MOVE for each mLeader Text to the x-axis target.
my 2 cents.
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

Chris

  • Swamp Rat
  • Posts: 548
Re: Aligning multileaders
« Reply #13 on: September 05, 2008, 11:52:10 AM »
in the first 2 try to align the top text with the bottom text
in the 3rd one try to align the bottom text with the top text
and the 4th one already works fine as is, it's just a scenario that needs to work in the completed program.
Christopher T. Cowgill, P.E.
AEC Collection 2020 (C3D)
Win 10

Chris

  • Swamp Rat
  • Posts: 548
Re: Aligning multileaders
« Reply #14 on: September 05, 2008, 11:57:16 AM »
I suspect that you will need to use the MOVE for each mLeader Text to the x-axis target.
my 2 cents.
See the attached picture, move on a multileader moves the entire entity.
Christopher T. Cowgill, P.E.
AEC Collection 2020 (C3D)
Win 10

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Aligning multileaders
« Reply #15 on: September 05, 2008, 12:04:27 PM »
So when you select the text and use the command MOVE the leader in it's entirety moves with it?
This is unlike the move with Qleader.
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Aligning multileaders
« Reply #16 on: September 05, 2008, 12:07:07 PM »
When you want the alignment, what part of the text is supposed to be aligned?
Left or Center or Right
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

Chris

  • Swamp Rat
  • Posts: 548
Re: Aligning multileaders
« Reply #17 on: September 05, 2008, 12:08:18 PM »
So when you select the text and use the command MOVE the leader in it's entirety moves with it?
This is unlike the move with Qleader.

that is correct.  With the qleader, only the point nearest the leader moves, when you move the text.  there are limitations to both, maybe I should just scrap the whole idea of using the multileaders and just stick with the qleader.  Maybe instead of working on fixing the multileader align, I should fix the move command with the qleader, so when you move text vertically, both the points on the tail move with the text.

we left justify and align the text on that left side.
Christopher T. Cowgill, P.E.
AEC Collection 2020 (C3D)
Win 10

Chris

  • Swamp Rat
  • Posts: 548
Re: Aligning multileaders
« Reply #18 on: September 05, 2008, 12:24:46 PM »
I found the problem, for the stretch start point, we are using the wrong piece of information, base on the entget of a multileader object, the part of the tail closest to the piece of text has absolutely nothing to do with any dxf code, directly. It is based on the farthest away point of the landing, minus the landing length, or at least it seems that way in the cases I have in this drawing

if you list the dxf codes of a multileader there are several codes that repeat, I think that inorder to get this to work, you must grab information from the following:

inside Context Data, you need code 12, this is the point that should be used for the stretch command
inside leader, you need the 10 code to determine the far end of the landing, the 11 code to determine if it is to the left or the right, and the 40 code to determine the current length of the landing
the pseudo code would look something like this:
Code: [Select]
get leader selection set
get ename of leader to align to
get the text location (dxf 12 in context data) of the leader to align to.
go through the list of enames
get the text location of the leader
get the 10 code
get the 11 code
get the 40 code
multiply the 40 code by 11 code
add to the 10 code x coord
select your point one based on the added x coord 10 value
select your box point 2 based on the same coord value)
stretch using c1 and c2 from lp to alxpt
end foreach
end if
end defun
now that that's all said, how do I select the codes based on their main header
Quote
((-1 . <Entity name: 7db06838>) (0 . "MULTILEADER") (330 . <Entity name:
7db04cf8>) (5 . "237") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0")
(100 . "AcDbMLeader") (300 . "CONTEXT_DATA{") (40 . 1.0) (10 13.4868 15.429
0.0) (41 . 0.08) (140 . 0.15) (145 . 0.04) (174 . 1) (175 . 1) (176 . 0) (177 .
0) (290 . 1) (304 . "here too") (11 0.0 0.0 1.0) (340 . <Entity name:
7db06488>) (12 13.5268 15.477 0.0) (13 1.0 0.0 0.0) (42 . 0.0) (43 . 0.0) (44 .
0.0) (45 . 1.0) (170 . 1) (90 . -1073741824) (171 . 1) (172 . 5) (91 .
-1073741824) (141 . 0.0) (92 . 14996616) (291 . 0) (292 . 0) (173 . 0) (293 .
0) (142 . 0.0) (143 . 0.0) (294 . 0) (295 . 0) (296 . 0) (110 13.4209 9.23386
0.0) (111 1.0 0.0 0.0) (112 0.0 1.0 0.0) (297 . 0) (302 . "LEADER{") (290 . 1)
(291 . 1) (10 16.7174 15.429 0.0) (11 -1.0 0.0 0.0) (90 . 1) (40 . 2.64392)
(304 . "LEADER_LINE{") (10 13.4209 9.23386 0.0) (10 16.7174 12.5304 0.0) (91 .
0) (305 . "}") (303 . "}") (301 . "}") (340 . <Entity name: 7db06800>) (90 .
263360) (170 . 1) (91 . -1073741824) (341 . <Entity name: 7db04ca8>) (171 . -1)
(290 . 1) (291 . 1) (41 . 3.23165) (42 . 0.15) (172 . 2) (343 . <Entity name:
7db06488>) (173 . 1) (95 . 1) (174 . 2) (175 . 0) (92 . -1073741824) (292 . 0)
(93 . -1056964608) (10 1.0 1.0 1.0) (43 . 0.0) (176 . 0) (293 . 0) (294 . 0)
(178 . 0) (179 . 1) (45 . 1.0))
« Last Edit: September 05, 2008, 01:05:17 PM by Chris »
Christopher T. Cowgill, P.E.
AEC Collection 2020 (C3D)
Win 10

ronjonp

  • Needs a day job
  • Posts: 7529
Re: Aligning multileaders
« Reply #19 on: September 05, 2008, 04:02:14 PM »
This is not very pretty but has passed the tests you posted earlier....let me know how it goes.

Code: [Select]
(defun c:alignlandings (/ al alpt cnt d1 dif dll doc el obj pt pt2 pt3 ss xpt)
  (setq doc (vla-Get-ActiveDocument (vlax-Get-Acad-Object)))
  (if (and (setq ss (ssget '((0 . "MULTILEADER"))))
   (setq al (car (entsel "\nSelect leader to align to: ")))
   (setq alpt (cdr (assoc 10 (entget al))))
   (setq xpt (car alpt))
      )
    (progn
      (vla-EndUndoMark doc)
      (vla-StartUndoMark doc)
      (foreach ml (vl-remove al
     (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss)))
  )
(setq obj (vlax-ename->vla-object ml)
      el  (entget ml)
      pt  (cdr (assoc 10 el))
      pt2 (list xpt (cadr pt))
      dif (distance pt pt2)
      dll (vla-get-DoglegLength obj)
      pt3 (polar pt (angle pt pt2) dll)
      d1  (distance pt alpt)
      cnt 0
)
(if (= (vla-get-DogLegged obj) :vlax-true)
  (progn
    (while (and (not (equal pt2 xpt 0.01))
(<= cnt 2)
   )
      (setq dif (* -1 dif))
      (vla-put-DoglegLength obj (+ dll dif))
      (vla-update obj)
      (setq el (entget (vlax-vla-object->ename obj))
    pt (cdr (assoc 10 el))
    pt2 (car pt)
    cnt (1+ cnt)
      )
    )
  )
)
      )
      (vla-EndUndoMark doc)
    )
  )
  (princ)
)
« Last Edit: September 05, 2008, 04:13:47 PM by ronjonp »

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

Chris

  • Swamp Rat
  • Posts: 548
Re: Aligning multileaders
« Reply #20 on: September 05, 2008, 04:08:18 PM »
no function definition on the rjp-vector_x function.

what about what I posted, wouldnt that work a little easier? (other than I dont know how to collect the data.)
Christopher T. Cowgill, P.E.
AEC Collection 2020 (C3D)
Win 10

ronjonp

  • Needs a day job
  • Posts: 7529
Re: Aligning multileaders
« Reply #21 on: September 05, 2008, 04:09:30 PM »
no function definition on the rjp-vector_x function.

what about what I posted, wouldnt that work a little easier? (other than I dont know how to collect the data.)

Re copy the code...I took that function out.

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

Chris

  • Swamp Rat
  • Posts: 548
Re: Aligning multileaders
« Reply #22 on: September 05, 2008, 04:13:17 PM »
yes, it does do what I need it to.  however, I would still like to know how to collect the data that I wanted to collect, just for future reference if I come across another object that has multiple dxf codes that are the same.
Christopher T. Cowgill, P.E.
AEC Collection 2020 (C3D)
Win 10

ronjonp

  • Needs a day job
  • Posts: 7529
Re: Aligning multileaders
« Reply #23 on: September 05, 2008, 04:18:57 PM »
The commented code I first posted should give you most of your answers.

and....you're welcome. :|

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

Chris

  • Swamp Rat
  • Posts: 548
Re: Aligning multileaders
« Reply #24 on: September 05, 2008, 04:30:01 PM »
I cant believe I was so rude :oops:, I thought for sure I had thanked you for your assistance.  Thank you, your assistance will allow me to start implementing the mleaders as our standard for notations.

Yes I understand (assoc 10 entdata) will give me the first 10 code in a dxf list, but what if there is a second?  I am not understanding how I would skip past the first 10 code and use the second one's information.
Christopher T. Cowgill, P.E.
AEC Collection 2020 (C3D)
Win 10

ronjonp

  • Needs a day job
  • Posts: 7529
Re: Aligning multileaders
« Reply #25 on: September 05, 2008, 04:52:00 PM »
This piece of code will return only the (assoc 10's....just supply it with an ename.

Code: [Select]
(mapcar 'cdr (vl-remove-if-not '(lambda (x) (= 10 (car x))) (entget ent)))
And you're welcome (with a smile this time)  :-)

If the mapcar is too confusing, you could use foreach like so:

Code: [Select]
(foreach e (entget (car (entsel)))
  (if (= 10 (car e))
    (setq lst (cons (cdr e) lst));;lst will hold the values you need
  )
)
« Last Edit: September 05, 2008, 04:58:45 PM by ronjonp »

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Aligning multileaders
« Reply #26 on: September 05, 2008, 05:03:03 PM »
Nice job Ron, that'll go into my goodie bag for future use.  8-)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

Chris

  • Swamp Rat
  • Posts: 548
Re: Aligning multileaders
« Reply #27 on: September 05, 2008, 05:04:50 PM »
yes, thanks, I will use that for future reference
Christopher T. Cowgill, P.E.
AEC Collection 2020 (C3D)
Win 10

ronjonp

  • Needs a day job
  • Posts: 7529
Re: Aligning multileaders
« Reply #28 on: September 05, 2008, 05:10:51 PM »
Nice job Ron, that'll go into my goodie bag for future use.  8-)

I think I stole that one from you..or someone around here:-D

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

Chris

  • Swamp Rat
  • Posts: 548
Re: Aligning multileaders
« Reply #29 on: December 17, 2008, 04:29:15 PM »
Ron, could you please comment a little on your align multileader program,  I have created a program that will allow text to extend under the dogleg, however, when I use this, and then try to align the multileaders, your program no longer aligns them properly.  I do believe it has to do with me assigning a negative leader gap, but when ever I attempt to align the leaders, I can never seem to get it to calculate the new dog leg length properly.  I would think it would be as simple as taking the original length difference, and then adding the negative value to the length. but that doesnt seem to work.

Here is what I have:

Code: [Select]
(defun c:mlgap (/     obj objent     objentdata
1stlinelnth lstln 1stlinelst  strlnt
exlandln    line llinelnth   vlaobjent
linelnth    lndif lnchng     lngap
landinggap leglen lncoord1 lncoord2
       )
  (if (setq obj (ssget))
    (progn
      (setq
objent    (ssname obj 0)
objentdata (entget objent)
vlaobjent  (vlax-ename->vla-object objent)
linelnth   0
      ) ;_ select object
      (typecheck)
      (if (equal (assoc 0 objentdata) '(0 . "MULTILEADER"))
(if (equal (car (cdr (assoc 11 (reverse objentdata)))) -1.0)
  (progn
  ;(setq tlocat (cdr (assoc 12 objentdata)))
  (setq 1stlinelnth (cdr (assoc 304 objentdata))
1stlinelst  (str2list 1stlinelnth "\\P")
lstln     (length 1stlinelst)
  ) ;_ end of setq
  (if (= Standardtype "ALLEGAN")
    (setq lngap 0.05
    ) ;_ end of setq
    (setq lngap 0.04
    ) ;_ end of setq
  ) ;_ end of if
  (foreach line 1stlinelst
    (setq
      strlnt (car (cadr (textbox (list (cons 1 line)
       (cons 7 "DIM")
       (cons 41 1.0)
       (cons 40 (* lngap 2))
) ;_ end of list
) ;_ end of textbox
  ) ;_ end of cadr
     ) ;_ end of car
    ) ;_ end of setq
    (if (= llinelnth nil)
      (setq llinelnth strlnt)
    ) ;_ end of if
    (if (< linelnth strlnt)
      (setq linelnth strlnt)
    ) ;_ end of if
  ) ;_ end of foreach
  (setq lndif (- linelnth llinelnth))
  (setq landinggap (* -1 (- lndif lngap)))
  (setq leglen (vlax-get-property vlaobjent 'DogLegLength))
  (vlax-put-property vlaobjent 'LandingGap landinggap)
  (setq txtbseptx (car (cdr (assoc 10 objentdata)))
txtbsepty (cadr (cdr (assoc 10 objentdata))))
  (if (> (+ (+ llinelnth lngap) (/ leglen 2)) (+ linelnth lngap))
    (setq lncoord1 (strcat (rtos (+ txtbseptx (+ (+ llinelnth lngap) (/ leglen 2))) 2 2) "," (rtos (+ txtbsepty (* 2 lngap)) 2 2) ",0")
  lncoord2 (strcat (rtos (- (+ landinggap txtbseptx) lngap) 2 2) "," (rtos (- (+ txtbsepty lngap) (/ (* lstln (/ (* 100 lngap) 30)))) 2 2) ",0"))
    (setq lncoord1 (strcat (rtos (+ txtbseptx (+ linelnth lngap)) 2 2) "," (rtos (+ txtbsepty (* 2 lngap)) 2 2) ",0")
  lncoord2 (strcat (rtos (- (+ landinggap txtbseptx) lngap) 2 2) "," (rtos (- (+ txtbsepty lngap) (/ (* lstln (/ (* 100 lngap) 30)))) 2 2) ",0"))
    )
  (vl-cmdf
    "stretch"
    "c"
    lncoord1
    lncoord2
    ""
    "0,0,0"
    (strcat
    (rtos (+ (* (* -1 landinggap) 2) (* 2 lngap)) 2 4)
    ",0,0"
    ) ;_ end of strcat
  ) ;_ end of vl-cmdf
) ;_ end of progn
  )
      ) ;_ end of if
    ) ;_ end of progn
  ) ;_ end of if
) ;_ end of defun

(defun Str2List (str pat / i j n lst)
  (cond
    ((/= (type str) (type pat) 'STR))
    ((= str pat) '(""))
    (T
     (setq i 0
   n (strlen pat)
     ) ;_ end of setq
     (while (setq j (vl-string-search pat str i))
       (setq lst (cons (substr str (1+ i) (- j i)) lst)
     i (+ j n)
       ) ;_ end of setq
     ) ;_ end of while
     (reverse (cons (substr str (1+ i)) lst))
    )
  ) ;_ end of cond
) ;_ end of defun


you could possibly have issues with the typecheck function and standardtype, as they are run from a separate file, just rem typecheck out and force lngap to be .05 and the text height is .1
here is what I have so far in modifying your program:
Code: [Select]
(defun c:multileaderalign
   (/ al alpt cnt d1 dif dll doc el obj pt pt2 pt3 ss xpt lng tht)
      (setq doc (vla-Get-ActiveDocument (vlax-Get-Acad-Object)))
      (if (and (setq ss (ssget '((0 . "MULTILEADER"))))
       (setq al (car (entsel "\nSelect leader to align to: ")))
       (setq alpt (cdr (assoc 10 (entget al))))
       (setq xpt (car alpt))
  ) ;_ end of and
(progn
  (vla-EndUndoMark doc)
  (vla-StartUndoMark doc)
  (foreach ml
   (vl-remove
     al
     (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss)))
   ) ;_ end of vl-remove
    (setq obj (vlax-ename->vla-object ml)
  el  (entget ml)
  pt  (cdr (assoc 10 el))
  pt2 (list xpt (cadr pt))
  dif (distance pt pt2)
  dll (vla-get-DoglegLength obj)
  pt3 (polar pt (angle pt pt2) dll)
  d1  (distance pt alpt)
  cnt 0
    ) ;_ end of setq
    (if (= (vla-get-DogLegged obj) :vlax-true)
      (progn
(while (and (not (equal pt2 xpt 0.01))
    (<= cnt 2)
       ) ;_ end of and
  (setq dif (* -1 dif))
  [color=red](if (/= (vla-get-landinggap obj) (/ (vla-get-textheight obj) 2))
    (setq lng (* -5 (vla-get-landinggap obj))
  tht (/ (* (vla-get-textheight obj) 1.02) -2))
    (setq lng 0
  tht 0)
)
  (vla-put-DoglegLength obj (+ dll dif tht lng))[/color]
  (vla-update obj)
  (setq el  (entget (vlax-vla-object->ename obj))
pt  (cdr (assoc 10 el))
pt2 (car pt)
cnt (1+ cnt)
  ) ;_ end of setq
) ;_ end of while
      ) ;_ end of progn
    ) ;_ end of if
  ) ;_ end of foreach
  (vla-EndUndoMark doc)
) ;_ end of progn
      ) ;_ end of if
      (princ)
    ) ;_ end of defun

I think the area highlighted in red is what I should be changing, but I cant get it to work.

Thanks for looking at this and setting me in the right direction.

Christopher T. Cowgill, P.E.
AEC Collection 2020 (C3D)
Win 10

ronjonp

  • Needs a day job
  • Posts: 7529
Re: Aligning multileaders
« Reply #30 on: December 17, 2008, 04:33:38 PM »
Chris,

Can you post a drawing with examples? That would help a bunch.

Ron

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

Chris

  • Swamp Rat
  • Posts: 548
Re: Aligning multileaders
« Reply #31 on: December 17, 2008, 05:02:14 PM »
yes, I will post them first thing tomorrow if I remember.
Christopher T. Cowgill, P.E.
AEC Collection 2020 (C3D)
Win 10

Chris

  • Swamp Rat
  • Posts: 548
Re: Aligning multileaders
« Reply #32 on: December 18, 2008, 07:48:37 AM »
Ron

Attached is a drawing with examples as you requested.
Christopher T. Cowgill, P.E.
AEC Collection 2020 (C3D)
Win 10

ronjonp

  • Needs a day job
  • Posts: 7529
Re: Aligning multileaders
« Reply #33 on: December 18, 2008, 06:51:03 PM »
Chris,

Just had a chance to look at this and at first glance I don't see an easy way to align your "new" leaders. The first point (red x) which was originally used to align the leaders has no consistency anymore?

Also,

Do you want the endpoint of the landing aligned or the left side of the text?

« Last Edit: December 18, 2008, 06:55:52 PM by ronjonp »

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

Chris

  • Swamp Rat
  • Posts: 548
Re: Aligning multileaders
« Reply #34 on: December 19, 2008, 07:57:49 AM »
Ok, now that I have a basis for what you were using, is there an easy way to modify the red x coord?  I'm sure that the difference in location can be determined based on the new leadergap length.  I dont believe I have ever been able to successfully change the coordinates of the red x.  You must have been able to in order for your code to work, could you show me the line that changes this value, then I could use it to modify the red coord and hopefully resolve the issue.
Christopher T. Cowgill, P.E.
AEC Collection 2020 (C3D)
Win 10

ronjonp

  • Needs a day job
  • Posts: 7529
Re: Aligning multileaders
« Reply #35 on: December 19, 2008, 09:56:17 AM »
Chris,

In my code, I was not modifying this point. I was stepping the landing length until it hit the X coord then stopped. That's why I said previously that the code was "not pretty".
You can change that first point location by using entmod like so:

(setq ed (entget (setq e (car (entsel)))))
(entmod (subst (cons 10 (getpoint)) (assoc 10 ed) ed))
(entupd e)

Per my previous post, what are you aligning to?

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

Chris

  • Swamp Rat
  • Posts: 548
Re: Aligning multileaders
« Reply #36 on: December 19, 2008, 10:06:32 AM »
as with the original program, I would like the left aligned text to be aligned along the left edge.  I will try changing the point and see if that resolves the issue.  If I change the point in my original mlgap program, then in theory, if your program uses the red x to align, the text should align properly.  Or am I missing the point?
Christopher T. Cowgill, P.E.
AEC Collection 2020 (C3D)
Win 10

ronjonp

  • Needs a day job
  • Posts: 7529
Re: Aligning multileaders
« Reply #37 on: December 19, 2008, 11:40:35 AM »
Here you go Chris...I was over thinking the problem. All I had to do was look for assoc 12 in the list rather than 10 :ugly:

Code: [Select]
(defun c:alignlandings (/ al alpt cnt dif dll doc el obj ss vs xpt xpt2)
  (setq doc (vla-get-activedocument (vlax-get-acad-object)))
  (if (and (setq ss (ssget ":L" '((0 . "MULTILEADER"))))
   (setq al (car (entsel "\nSelect leader to align to: ")))
   (setq alpt (cdr (assoc 12 (entget al))))
   (setq xpt (car alpt))
   (setq vs (getvar 'viewsize))
      )
    (progn (vla-endundomark doc)
   (vla-startundomark doc)
   (grdraw (polar alpt (angtof "90") vs) (polar alpt (angtof "270") vs) 1)
   (foreach ml (vl-remove al (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))))
     (setq el (entget ml)
   obj (vlax-ename->vla-object ml)
   xpt2 (cadr (assoc 12 el))
   dif (abs (- xpt xpt2))
   cnt -1
     )
     (if (minusp (vlax-get obj 'doglegged))
       (progn (setq dll (vla-get-dogleglength obj))
      (while (and (not (equal xpt xpt2 0.01)) (< (setq cnt (1+ cnt)) 2))
(vla-put-dogleglength obj (+ dll (setq dif (- dif))))
(setq xpt2 (cadr (assoc 12 (entget ml))))
      )
       )
     )
     (vla-update obj)
   )
   (vla-endundomark doc)
    )
  )
  (princ)
)
« Last Edit: February 10, 2010, 03:40:17 PM by ronjonp »

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

Chris

  • Swamp Rat
  • Posts: 548
Re: Aligning multileaders
« Reply #38 on: December 19, 2008, 11:52:48 AM »
once again, thanks for your help, so based on the coding, it looks like I can just replace multileaderalign with this new version of the program?
Christopher T. Cowgill, P.E.
AEC Collection 2020 (C3D)
Win 10

ronjonp

  • Needs a day job
  • Posts: 7529
Re: Aligning multileaders
« Reply #39 on: December 19, 2008, 11:56:55 AM »
Yes you can replace the code...and you are welcome :)

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

cadpoobah

  • Newt
  • Posts: 48
Re: Aligning multileaders
« Reply #40 on: November 12, 2013, 02:18:20 PM »
ronjonp,

I know this is an old post, but wanted to keep my feedback with the rest of this thread.

Your "AlignLandings" is great but had me scratching my head on the alignment results until I factored in the annotation scale of the selected multileaders. I modified your "dif" variable equation as shown:
from:  dif (abs (- xpt xpt2))
    to:  dif (* (abs (- xpt xpt2)) (getvar "CANNOSCALEVALUE"))

Of course, this revised code now makes the dangerous assumption that the mleader is annotative (which ours are). I'll leave it to someone else to make it more adaptive.

Code: [Select]
(defun c:alignlandings (/ al alpt cnt dif dll doc el obj ss vs xpt xpt2)
  (setq doc (vla-get-activedocument (vlax-get-acad-object)))
  (if (and (setq ss (ssget ":L" '((0 . "MULTILEADER"))))
   (setq al (car (entsel "\nSelect leader to align to: ")))
   (setq alpt (cdr (assoc 12 (entget al))))
   (setq xpt (car alpt))
   (setq vs (getvar 'viewsize))
      )
    (progn (vla-endundomark doc)
   (vla-startundomark doc)
   (grdraw (polar alpt (angtof "90") vs) (polar alpt (angtof "270") vs) 1)
   (foreach ml (vl-remove al (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))))
     (setq el (entget ml)
   obj (vlax-ename->vla-object ml)
   xpt2 (cadr (assoc 12 el))
   dif (* (abs (- xpt xpt2)) (getvar "CANNOSCALEVALUE"))
   cnt -1
     )
     (if (minusp (vlax-get obj 'doglegged))
       (progn (setq dll (vla-get-dogleglength obj))
      (while (and (not (equal xpt xpt2 0.01)) (< (setq cnt (1+ cnt)) 2))
(vla-put-dogleglength obj (+ dll (setq dif (- dif))))
(setq xpt2 (cadr (assoc 12 (entget ml))))
      )
       )
     )
     (vla-update obj)
   )
   (vla-endundomark doc)
    )
  )
  (princ)
)

Regards,

Chris
Chris Lindner
Onebutton CAD Solutions
----------------------------------------------------
www.onebuttoncad.com #dayjob
www.unpavedart.com    #sidehustle

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Aligning multileaders
« Reply #41 on: November 12, 2013, 02:47:41 PM »
The following predicate function will return T if an entity is annotative:

Code - Auto/Visual Lisp: [Select]
  1. (defun annotative-p ( ent / dic )
  2.     (and
  3.         (member  '(102 . "{ACAD_XDICTIONARY") (setq ent (entget ent)))
  4.         (setq dic (cdr (assoc 360 ent)))
  5.         (setq dic (dictsearch dic "acdbcontextdatamanager"))
  6.         (setq dic (dictsearch (cdr (assoc -1 dic)) "acdb_annotationscales"))
  7.         (dictnext (cdr (assoc -1 dic)) t)
  8.     )
  9. )

Implemented in Ron's program:
Code - Auto/Visual Lisp: [Select]
  1. (* (abs (- xpt xpt2)) (if (annotative-p ml) (getvar 'cannoscalevalue) 1.0))

ronjonp

  • Needs a day job
  • Posts: 7529
Re: Aligning multileaders
« Reply #42 on: November 12, 2013, 04:41:42 PM »
ronjonp,

I know this is an old post, but wanted to keep my feedback with the rest of this thread.

Your "AlignLandings" is great but had me scratching my head on the alignment results until I factored in the annotation scale of the selected multileaders. I modified your "dif" variable equation as shown:
from:  dif (abs (- xpt xpt2))
    to:  dif (* (abs (- xpt xpt2)) (getvar "CANNOSCALEVALUE"))

Of course, this revised code now makes the dangerous assumption that the mleader is annotative (which ours are). I'll leave it to someone else to make it more adaptive.

Regards,

Chris

Chris,

Glad you could make use of the routine. I've added Lee's annotative sub as well as check the scale factor of the mleader. When it was not equal to 1 the results were funny.

Code: [Select]
(defun c:alignlandings (/ annotative-p al alpt cnt dif dll doc o ss vs xpt xpt2)
  (vl-load-com)
  ;; Lee Mac to check if object is annotative
  (defun annotative-p (ent / dic)
    (and (member '(102 . "{ACAD_XDICTIONARY") (setq ent (entget ent)))
(setq dic (cdr (assoc 360 ent)))
(setq dic (dictsearch dic "acdbcontextdatamanager"))
(setq dic (dictsearch (cdr (assoc -1 dic)) "acdb_annotationscales"))
(dictnext (cdr (assoc -1 dic)) t)
    )
  )
  (setq doc (vla-get-activedocument (vlax-get-acad-object)))
  (if (and (setq ss (ssget ":L" '((0 . "MULTILEADER"))))
   (setq al (car (entsel "\nSelect leader to align to: ")))
   (setq alpt (cdr (assoc 12 (entget al))))
   (setq xpt (car alpt))
   (setq vs (getvar 'viewsize))
      )
    (progn (vla-endundomark doc)
   (vla-startundomark doc)
   (grdraw (polar alpt (angtof "90") vs) (polar alpt (angtof "270") vs) 1)
   (foreach ml (vl-remove al (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))))
     (if (minusp (vlax-get (setq o (vlax-ename->vla-object ml)) 'doglegged))
       (progn (setq xpt2 (cadr (assoc 12 (entget ml)))
    ;; RJP added scalefactor so landing length is calculated correctly when /= 1
    dif (* (abs (- xpt xpt2))
    (if (annotative-p ml)
      (getvar 'cannoscalevalue)
      (/ 1. (vla-get-scalefactor o))
    )
)
    cnt -1
    dll (vla-get-dogleglength o)
      )
      (while (and (not (equal xpt xpt2 0.01)) (< (setq cnt (1+ cnt)) 2))
(vla-put-dogleglength o (+ dll (setq dif (- dif))))
(setq xpt2 (cadr (assoc 12 (entget ml))))
      )
       )
     )
     (vla-update o)
   )
   (vla-endundomark doc)
    )
  )
  (princ)
)
« Last Edit: November 12, 2013, 04:46:04 PM by ronjonp »

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC