Author Topic: Aligning multileaders  (Read 18664 times)

0 Members and 1 Guest are viewing this topic.

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