Mline swap LSP routine

Mline swap LSP routine

joe_kohli
Advocate Advocate
1,801 Views
20 Replies
Message 1 of 21

Mline swap LSP routine

joe_kohli
Advocate
Advocate

So, I want to create a lsp that will do the following: do an Mline "Swap"

 

Essential, (in my attached dwg file) I want to basically select an Mline (for example the "0200 AQUA") and if I select the "0036 50% UREA" Mline, it will change it to "0220 AQUA". 

 

Initially, select the desired Mline that you want to use as your baseline and go find the Mline you want to convert. Once you select the Mline, it will change to match the initial selection. Now you have 2 Mlines that are showing EXACTLY the same. 

0 Likes
Accepted solutions (1)
1,802 Views
20 Replies
Replies (20)
Message 2 of 21

Kent1Cooper
Consultant
Consultant

Does MATCHPROP not do what you want?  If not, describe in more detail.

Kent Cooper, AIA
0 Likes
Message 3 of 21

joe_kohli
Advocate
Advocate

MATCHPROP only change the color. It does not change the properties to match. I will try to use the command and show you. Once the command is prompted, I select the "0200 AQUA" and then I select the "0036 50% UREA" and all it does is change the backround color of the Mline.

 

Before MATCHPROP:

joe_kohli_0-1722866535097.png

 

 

After MATCHPROP:

joe_kohli_1-1722866560417.png

 

0 Likes
Message 4 of 21

Kent1Cooper
Consultant
Consultant

[It doesn't just change the color, but also the Layer.]  I didn't realize that MultiLines are some kind of orphan object type -- MATCHPROP won't match their Mline Style.  And even though the Style is an entry in their entity data [DXF code 2], I've tried various ways of substituting that from one into the other, so far without success.  I also tried to assign the StyleName VLA property, with the same non-result.  Maybe I just haven't found the right way yet....

But there may not be one -- I also notice that in the Properties palette, the Style is listed, but greyed out, so it can't even be assigned there.  It may be that you're stuck with drawing a new one over the one you want changed.

Kent Cooper, AIA
0 Likes
Message 5 of 21

joe_kohli
Advocate
Advocate

Ya I was afraid of that. So let me ask you this....I'm sure you played with them in the drawing I attached. Is there an eaiser way (possibly bypassing Mline) to create these banners? Almost like a poly line?

0 Likes
Message 6 of 21

Kent1Cooper
Consultant
Consultant

@joe_kohli wrote:

.... Is there an eaiser way (possibly bypassing Mline) to create these banners? ....


What are they used for?

 

Do you ever really want them long enough to contain multiple repeats of the text-content part?  If you only use them in short-enough pieces to have that once, stuck onto some kind of path object [at intervals, perhaps?], would a Block do it?

Kent Cooper, AIA
0 Likes
Message 7 of 21

joe_kohli
Advocate
Advocate

They are used to show what product is going through a line via P&ID dwg. So typically you would draw a line or polyline to indicate your process line/piping. Then, you would use those Mlines to snap to the bottom of that process line to show what system it is. Yes, they need to continue to repeat the text-content.

 

See the example below. The top line is just an indication that it is a "process" line. The bottom still shows that it is a "process" line but also has the system/material snapping to the process line to show you what is in that particular line. So I have "0022 PRS AIR" flowing to a gate valve and after the gate valve the system switches to "0008 50# STM". Hope this makes sense.

 

joe_kohli_0-1722875486677.png

 

0 Likes
Message 8 of 21

Moshe-A
Mentor
Mentor
Accepted solution

@joe_kohli  hi,

 

Check this MML (Match Mline) command, works for me 😀

 

enjoy

Moshe

 

 

 

(vl-load-com) ; load activex support

; match mline

(defun c:mml (/ match_mline ; local function
		acadObj adoc dict ss0 ss1 ename0 ename1 AcDbMline0 AcDbMline1 AcDbMline2)

 (defun match_mline (AcDbSor AcDbTar / dictName AcDbMLineStyleTableRecord c340 elist lst)
  (setq dictName (vla-get-styleName AcDbSor))
  (setq AcDbMLineStyleTableRecord (vla-item (vla-item dict "ACAD_MLINESTYLE") dictName))
  (setq c340 (cons '340 (cdar (entget (vlax-vla-object->ename AcDbMLineStyleTableRecord)))))
    
  (setq elist (entget (vlax-vla-object->ename AcDbTar)))   
  ; chop '(-1 5 330) items
  (setq lst (vl-remove-if
	      'not
              (mapcar
	       '(lambda (item)
                 (if (not (member (car item) '(-1 5 330)))
	          item
	         )
	        ); lambda
	        elist
              ); mapcar
            ); vl-remove-if
  ); setq 

  (entmake (subst c340 (assoc '340 lst) lst)) ; copy exising mline
 ); match_mline


 ; here start c:mml
 (setq acadObj (vlax-get-acad-object))
 (setq adoc (vla-get-activedocument acadObj))
 (setq dict (vla-get-dictionaries adoc))

 (vla-startUndoMark adoc)
  
 (if (and
       (not (prompt "\nSelect source mline: "))
       (setq ss0 (ssget ":s:e+." '((0 . "mline"))))
       (not (prompt "\nSelect target mline(s): "))
       (setq ss1 (ssget '((0 . "mline"))))
     )
  (progn
   (setq ename0 (ssname ss0 0))
   
   (if (ssmemb ename0 ss1)
    (ssdel ename0 ss1)
   )

   (setq AcDbMline0 (vlax-ename->vla-object ename0))
   
   (foreach ename1 (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss1)))
    (setq AcDbMline1 (vlax-ename->vla-object ename1))
    (if (match_mline AcDbMline0 AcDbMline1)
     (progn
      (setq AcDbMline2 (vlax-ename->vla-object (entlast)))
      (vla-put-layer AcDbMline2 (vla-get-layer AcDbMline0))
      (vlax-release-object AcDbMline2)
      (vla-delete AcDbMline1) ; delete origin mline
     ); progn
    ); if
    (vlax-release-object AcDbMline1)
   ); foreach

   (vlax-release-object AcDbMline0)
  ); progn
 ); if

 (vla-endUndoMark adoc)
  
; dispose memory
 (foreach obj (list dict adoc)
  (if obj (vlax-release-object obj))
 )

 (princ)
); c:mml 
Message 9 of 21

joe_kohli
Advocate
Advocate

Nice fix!!! Thank you!

0 Likes
Message 10 of 21

ronjonp
Mentor
Mentor

@joe_kohli Is there a reason that you don't use polylines with a linetype for the text? In my experience, mlines are not the easiest to work with.

ronjonp_0-1722890943046.png

*0036 50% UREA,0036 50% UREA» ----------0036 50% UREA----------0036 50% UREA----------0036 50% UREA----------
A,0.5,-0.812909,["0036 50% UREA",Arial,S=0.15,U=0,X=-0.796606,Y=-0.0735164],-0.812909
0 Likes
Message 11 of 21

Sea-Haven
Mentor
Mentor

Like @ronjonp it is possible to write a line type on the fly and then load it into the current dwg, so if needing a new one could simply add to say a custom.lin.

0 Likes
Message 12 of 21

Moshe-A
Mentor
Mentor

@joe_kohli ,

 

WOW this score was quick , thank you very much 😀

 

One thing to note:

You already understand that modification of mline(s) is not straightforward either manually from the properties palette nor from AutoLisp\ActiveX, so the solution of MML is to draw another mline on top of the existing (plus change it's layer)

 

Are you ok with that?!

 

Moshe

 

0 Likes
Message 13 of 21

joe_kohli
Advocate
Advocate
I actually have been told several times that the way you are showing is the correct way of doing it. I may get with you on how you did this. Would like to have a way to add new systems very quickly, on the fly. This is a perfect solution.
0 Likes
Message 14 of 21

joe_kohli
Advocate
Advocate

Yes, this will definitely work for what I need as of right this minute but I will have to move into using polylines with linetypes as a more permanent solution.

0 Likes
Message 15 of 21

Kent1Cooper
Consultant
Consultant

@Kent1Cooper wrote:

....  It may be that you're stuck with drawing a new one over the one you want changed.


Experimenting with that as an automated approach, I arrived at this:

(defun C:MLMP ; = MultiLine Match Properties
  (/ ML1 ML1data ML2 ML2data)
  (setq
    ML1 (car (entsel "\nSource MLine: "))
    ML1data (entget ML1)
    ML2 (car (entsel "\nTarget MLine to match Source: "))
    ML2data (entget ML2)
  ); setq
  (setvar 'ltscale (cdr (assoc 48 ML1data)))
  (command
    "_.layer" "_set" (cdr (assoc 8 ML1data)) "" ; set properties to match ML1
    "_.mline"
    "_justification" (nth (cdr (assoc 70 ML1data)) '("Top" "Zero" "Bottom"))
    "_scale" (cdr (assoc 40 ML1data))
    "_style" (cdr (assoc 2 ML1data))
  ); leave in MLINE command:
  (foreach pt ; points in ML2
    (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 11)) ML2data))
    (command pt)
  ); foreach
  (command ""); conclude MLINE
  (entdel ML2)
  (prin1)
)

It works in your sample drawing, and also with MLines of more than one segment, but there are oddities:

Its results sometimes [not always, for some reason] end up with larger text size.  Properties shows both the linetype scale and the Mline scale as the same, but the text size is bigger.  I don't have any idea what could cause that, nor therefore how to prevent it.

 

And I tried a couple of ways of getting it to work if the target Mline is closed, both feeding in the "_close" option and imposing the entity-data entry that contains the code for that, without success.

 

I think Mlines are peculiar in more ways than simply not being able to change their Style after the fact....

Kent Cooper, AIA
0 Likes
Message 16 of 21

ronjonp
Mentor
Mentor

@joe_kohli wrote:
I actually have been told several times that the way you are showing is the correct way of doing it. I may get with you on how you did this. Would like to have a way to add new systems very quickly, on the fly. This is a perfect solution.

Let me know if you need anymore help. This could easily be automated.

 

As a start, you could use my MAKELT routine to easily create your linetype definitions.

0 Likes
Message 17 of 21

Kent1Cooper
Consultant
Consultant

@ronjonp wrote:

.... you could use my MAKELT routine to easily create your linetype definitions.


Or, without the need for any custom routine, just use AutoCAD's built-in MKLTYPE command, which very quickly and easily made this one:

Kent1Cooper_1-1722967579381.png

 

Kent Cooper, AIA
0 Likes
Message 18 of 21

ronjonp
Mentor
Mentor

@Kent1Cooper wrote:

@ronjonp wrote:

.... you could use my MAKELT routine to easily create your linetype definitions.


Or, without the need for any custom routine, just use AutoCAD's built-in MKLTYPE command, which very quickly and easily made this one:

Kent1Cooper_1-1722967579381.png

 


@Kent1Cooper Yes there is the "built-in" LMFTFY "folded in" express tools version. Not a fair comparison IMO. As far as I've seen, the base code for express tools is stuck in the 1990's to early 2000's and not being improved.

 

ronjonp_0-1722985444928.png

Here's showing how outdated the code is.

Command: MKLTYPE
(*pop-error-mode*) underflow.
Cannot invoke (command) from *error* without prior call to (*push-error-using-command*).
Converting (command) calls to (command-s) is recommended.

A much simpler way to create and or update linetypes. *clink*

ronjonp_1-1722985627625.png

0 Likes
Message 19 of 21

Kent1Cooper
Consultant
Consultant

@ronjonp wrote:

....

Here's showing how outdated the code is.

Command: MKLTYPE
(*pop-error-mode*) underflow.
Cannot invoke (command) from *error* without prior call to (*push-error-using-command*).
Converting (command) calls to (command-s) is recommended.

...


The better relationship of the text part to curves is nice [and I've often done that kind of thing with linetype definitions that I spell out], if the OP would ever use such a thing on curves -- do P&ID drawings ever do that?

 

But just so you know:  I do not get that underflow message or the rest when I use MKLTYPE.  It works perfectly normally for me, at both Acad2020 and Acad2024 installations.  Something must be wrong with your installation.

Kent Cooper, AIA
0 Likes
Message 20 of 21

ronjonp
Mentor
Mentor

@Kent1Cooper wrote:

@ronjonp wrote:

....

Here's showing how outdated the code is.

Command: MKLTYPE
(*pop-error-mode*) underflow.
Cannot invoke (command) from *error* without prior call to (*push-error-using-command*).
Converting (command) calls to (command-s) is recommended.

...


The relationship of the text part to curves is nice, if the OP would ever use such a thing on curves.

 

But just so you know:  I do not get that underflow message or the rest when I use MKLTYPE.  It works normally for me, at both Acad2020 and Acad2024 installation.  Something must be wrong with your installation.


Nothing wrong with my install ( 2025 ) but I sure can break that "built in code", it's my norm.

I don't rely on express tools ever, but that's just me. *clinks*

0 Likes