Creating MultiLine Style

Creating MultiLine Style

ebsoares
Collaborator Collaborator
4,700 Views
18 Replies
Message 1 of 19

Creating MultiLine Style

ebsoares
Collaborator
Collaborator

Hi, everyone.

Was wondering if there is a way to create multiline styles using Visual Lisp code (vla or vlax).

I found this post ("Is it possible to make a Multiline Style with LISP?" - AUGI), but the the solution provided uses a list and dxf codes, which I really don't like to use (but if you're "fixo", thanks for posting that answer anyway, since it definitely works and has undoubtedly helped many folks by now 😊).

If it is possible to use VLA language, I'd appreciate some help in working on it and a list of the properties available for the coding.

Thanks in advance!

0 Likes
Accepted solutions (1)
4,701 Views
18 Replies
Replies (18)
Message 2 of 19

devitg
Advisor
Advisor

@ebsoares Hi , I'm no Fixo , he was my friend and LISP teacher , sad to say Fixo as passed away , circa 2014 . He was from St Petersburg Russia . If you see his Forum.augi avatar , he show me he cheers for Argentina  the World cup  at Germany . 

I will try to help you . 

Why do you want to do it by VL ??

 

 

 
 

 

 

 

 

0 Likes
Message 3 of 19

ebsoares
Collaborator
Collaborator

Hi, @devitg, thanks for offering to help. And sorry to hear Fixo passed away - I remember using some of his solutions through the years...

There's just a couple reasons I prefer VL code:

. I'm not a big fan of using lists, specially using the quote symbol at the beginning of the code sentence (sometimes I get glitches I don't know how to fix).

. dxf codes are not as obvious or clear as VL code, since VL code specifically mentions what they are doing (vla-put-property... is much more clear as to what it is doing than 70 . 721...).

Any help would be appreciated.

0 Likes
Message 4 of 19

Sea-Haven
Mentor
Mentor

If you create a custom mln then you can load and set as default. Save a mln file and open just need to work out what values are. You can add to a txt type file using "A" option to write file so could create a new linetype on the fly.

 

This may be useful also https://autocadtips1.com/2011/06/17/improved-mline-multiline/

 

3 lines -1, 0.0, 1 

 

 

MLSTYLE
  2
NewStyle1
 70
     0
  3

 62
   256
 51
90.0
 52
90.0
 71
     3
 49
1.0
 62
   256
  6
BYLAYER
 49
0.0
 62
   256
  6
BYLAYER
 49
-1.0
 62
   256
  6
BYLAYER
0

 

 

Just need to keep googling make a mnl like custom dont use the "acad.mnl" could load and check if mline exists or make a new one and load perhaps just have one, the other googling suggested adding to the dwg dictionary.

; by gilsoto13 

(defun C:mstyles ()
  (setq rgm (getvar "regenmode"))
  (command "setvar" "regenmode" 0)
  (command "mspace" ".change" "all" "" "p" "ltscale" "1" "" "pspace")
  (command ".mline" "style" "job1" (strcat "C:/Standard/acad.mnl") "" "")
  (command ".mline" "style" "job2" (strcat "C:/Standard/acad.mnl") "" "")
  (command ".mline" "style" "job2" (strcat "C:/Standard/acad.mnl") "" "")
  (command ".mline" "style" "job3" (strcat "C:/Standard/acad.mnl") "" "")
  (command "setvar" "regenmode" rgm)
; It works
  (princ)
)

  

0 Likes
Message 5 of 19

ebsoares
Collaborator
Collaborator

Thanks for the tip, @Sea-Haven, but I would like to maintain my lisp routine more generic and not dependent on the ability to find files outside of the drawing.

I already have a piece of code that checks for existing MLine styles. Now I would just like to be able to generate code that simply creates a MLine style using VLA language.

Would you happen to know if that is possible at all?

0 Likes
Message 6 of 19

ronjonp
Advisor
Advisor

Here's one that I put together many many moons ago. You can modify it to suit your needs 🙂

 

(defun _makemleaderstyle (name txtstyle / mldict mlobj)
  (if (and (setq mldict (cdr (assoc -1 (dictsearch (namedobjdict) "acad_mleaderstyle"))))
	   (setq mldict (vlax-ename->vla-object mldict))
	   (not	(vl-catch-all-error-p
		  (setq	mlobj
			 (vl-catch-all-apply 'vlax-invoke (list mldict 'addobject name "AcDbMLeaderStyle"))
		  )
		)
	   )
      )
    (progn (vla-put-breaksize mlobj 0.1)
	   (vla-put-description mlobj "")
	   (vla-put-dogleglength mlobj 0.125)
	   (vla-put-enablelanding mlobj :vlax-true)
	   (vla-put-firstsegmentangleconstraint mlobj 0)
	   (vla-put-landinggap mlobj 0.05)
	   (vla-put-maxleadersegmentspoints mlobj 2)
	   ;;(vla-put-scalefactor mlobj 1)
	   (vla-put-secondsegmentangleconstraint mlobj 0)
	   (vlax-put mlobj 'textalignmenttype 0)
	   (vlax-put mlobj 'textleftattachmenttype 1)
	   (vlax-put mlobj 'textrightattachmenttype 1)
	   (vla-put-textheight mlobj 0.1)
	   (vla-put-textstyle
	     mlobj
	     (if (tblobjname "style" txtstyle)
	       txtstyle
	       "standard"
	     )
	   )
	   mlobj
    )
  )
)
;; (_makemleaderstyle "TestFoo2" "Arial")

 

0 Likes
Message 7 of 19

Sea-Haven
Mentor
Mentor

Why not create the mln file, load it, then erase it. Use the  vl-filename-mktemp function.

0 Likes
Message 8 of 19

ebsoares
Collaborator
Collaborator

Thanks for the post @ronjonp, but it seems you have posted a solution for creating Mleaders using VLA (which I already have), instead of MLine (multiline).

Thanks anyway 😉

0 Likes
Message 9 of 19

ebsoares
Collaborator
Collaborator

Thanks @Sea-Haven, but I am really not interested in anything other than a single *.lsp file, which can run in an AutoCAD session and create multiline styles on the spot.

Would you happen to know if it is possible to create such a code using VLA code?

0 Likes
Message 10 of 19

Sea-Haven
Mentor
Mentor

It is difficult to avoid the mline dcls so this is a bit of a work around, the default search is for acad.mln but it can live in a directory, a couple of buts it must be in the support paths and it must be say at top of list. So replace alan\\lisp with yours.

 

For this type offsets, press enter 

When dcl opens click on acad.mln 

It not perfect but mline is started so pick pick pick.

 

I am sure other options could be added layers / colors, caps.

(defun c:makml ( / lst fo stname )
(while (setq off (getreal "\nEnter offset enter to stop  " ))
	(setq lst (cons off lst))
)
; change directory name to suit
(setq fo (open (setq fname "D:\\Alan\\lisp\\acad.mln") "w"))
(write-line "MLSTYLE" fo)
(write-line "2" fo )
(setq stname (getstring "\nEnter style name note use quotes if space in name"))
(write-line stname fo )
(write-line "70" fo )
(write-line "0" fo )
(write-line "3" fo )
(write-line (getstring "\nEnter description") fo )
(write-line "62" fo )
(write-line "256" fo )
(write-line "51" fo )
(write-line "90.0" fo )
(write-line "52" fo )
(write-line "90.0" fo )
(write-line "71" fo )
(setq x (length lst))
(write-line (rtos x 2 0) fo)
(repeat x
(write-line "49" fo )
(write-line (rtos (nth (setq x (- x 1)) lst) 2 2) fo )
(write-line "62" fo )
(write-line "256" fo )
(write-line "6" fo )
(write-line "BYLAYER" fo )
)
(write-line "BYLAYER" fo )
(write-line "0" fo )
(close fo)
(command ".mline" "style" stname "D:\\Alan\\lisp\\acad.mln" "" "")
(princ)
)
(c:makml)

  

0 Likes
Message 11 of 19

ronjonp
Advisor
Advisor

@ebsoares  Oooops 🤓

0 Likes
Message 12 of 19

pbejse
Mentor
Mentor

@ronjonp wrote:

Oooops 🤓


I can recommend a good eye doctor if you're interested 😀

eye doctor.png

 

 

 

 

0 Likes
Message 13 of 19

ronjonp
Advisor
Advisor

@pbejse wrote:

@ronjonp wrote:

Oooops 🤓


I can recommend a good eye doctor if you're interested 😀

eye doctor.png

 

 

 

 


Do you know a good shrink as well? 😂

0 Likes
Message 14 of 19

ebsoares
Collaborator
Collaborator

Thanks for the code, @Sea-Haven, but I'd really like to avoid handling external files for this routine.

 

Changing gears a bit - I will assume it is not possible to create MLines using VLA coding then.

 

Let's work with Fixo's code:

I have tried it and it works. It creates a new multiline style with two inner lines (color "red") and two outer lines (color "bylayer"):

Screenshot 2020-10-13 123819.png

 

And here's Fixo's unedited code:

(defun C:demo ()
;;;(setvar "CLAYER" "ANNO-ARCH-WALL")
(setq MLINE_STYLE_NAME "WALLS"
INNER_GAP 0.92
OUTER_GAP 1.04)
(if
(not
(dictadd
(cdar (dictsearch (namedobjdict) "ACAD_MLINESTYLE"))
MLINE_STYLE_NAME
(entmakex
(list '(0 . "MLINESTYLE")
'(100 . "AcDbMlineStyle")

(cons 2 MLINE_STYLE_NAME)
'(70 . 0)
'(3 . "")
'(62 . 256)
'(51 . 1.5708)
'(52 . 1.5708)
'(71 . 4)
(cons 49 OUTER_GAP)
'(62 . 256)
'(6 . "BYLAYER")
(cons 49 INNER_GAP)
'(62 . 1)
'(6 . "BYLAYER")
(cons 49 (* -1 INNER_GAP))
'(62 . 1)
'(6 . "BYLAYER")
(cons 49 (* -1 OUTER_GAP))
'(62 . 256)
'(6 . "BYLAYER")))))
(alert "Impossible to create mline style\n perhaps this was exist earlier"))
(princ)
)

 

The above works well if one would like to create said MLine. However, I am interested in simply creating MLines with two lines (so, only using "outer_gap"). But when I simply delete the portion from his code above that is bold red, I end up with the following:

Screenshot 2020-10-13 123849.png

The bottom line ends up with color "byblock" and linetype "continuous".

 

Does anyone know how to fix this issue and help me end up with all properties set to "bylayer"

 

Thanks in advance 😊

0 Likes
Message 15 of 19

Sea-Haven
Mentor
Mentor
Accepted solution

You need to understand what some of the dxf codes represent, compare the following, big hints.

 

(62 . 256)  (62 . 1)

(72 . 4)  (72 . 2)

 

(3 . "description")

 

Make a linetype save to a file and open can see the differences look at the numbers, change 1 thing at a time color, layer etc.

 

Start at page 5 https://images.autodesk.com/adsk/files/autocad_2012_pdf_dxf-reference_enu.pdf

 

Need to take the fixo code and blend what I suggested but with a few more options I just did bylayer as a starting point. Something like offset,colour,layer

 

 

0 Likes
Message 16 of 19

Sea-Haven
Mentor
Mentor

Ok next go makes multi offset and by layer next version would have more options.

 

 

; make mline 
; By alan H oct 2020
; Set to bylayer at moment
; Thanks to FIXO for original code

(defun c:makml ( / lst1 lst2 lst desc MLINE_STYLE_NAME off)
(setq 	MLINE_STYLE_NAME (getstring "\nEnter mline name ")
		desc (getstring "\nEnter description ")
)
(while (setq off (getreal "\Enter offset Enter to finish " ))
	(setq lst (cons off lst))
)
(if (= desc nil)(setq desc MLINE_STYLE_NAME))
(setq lst1
	(list '(0 . "MLINESTYLE")
		'(100 . "AcDbMlineStyle")
		(cons 2 MLINE_STYLE_NAME)
		'(70 . 0)
		(cons 3 desc)
		'(62 . 256)
		'(51 . 1.5708)
		'(52 . 1.5708)
		'(71 . 4)
	)
)
(setq x (length lst))
(repeat x
	(setq lst2 (list 
		(cons 49 (nth (setq x (- x 1)) lst))
		(cons 62 256)
		(cons 6 "BYLAYER")
		)
	)
	(setq lst1 (append lst1 lst2))
)

(if
	(not (dictadd
		(cdar (dictsearch (namedobjdict) "ACAD_MLINESTYLE"))
		MLINE_STYLE_NAME
		(entmakex lst1)
		)
	)
	(Alert "Impossible to create mline style\n perhaps this was exist earlier")
)
(setvar 'cmlstyle MLINE_STYLE_NAME)
(princ)
)
(c:makml)

 

Message 17 of 19

ebsoares
Collaborator
Collaborator

A-ha! Thanks for isolating the DXF code 71! I did check all the DXF codes and understood their meaning before I even started this post - except 71, which I did not notice - it is asking how many lines the MLine will have 😄

Now there's no issue with Fixo's code - I just need to change code 71 to 2.

Thanks again, @Sea-Haven and everyone else who has been trying to help me out here

Cheers!

0 Likes
Message 18 of 19

Sea-Haven
Mentor
Mentor

No worries the code I posted allows you to enter multiple offsets and create as required rather than hard coded.

Message 19 of 19

yaxgaustria
Explorer
Explorer

Hello there. This works for my everyday drawing needs;

 

;; LAYERS TO USE LAYERS TO USE LAYERS TO USE LAYERS TO USE LAYERS TO USE LAYERS TO USE ;;

;; New layer, yxTEMP
(setq flag (tblsearch "layer" "yxTEMP"))
; find out if the layer exists
(if flag ; if the layer exists
(progn
(command "_.layer" "_on" "yxTEMP" "") ; if the layer is off
(command "_.layer" "_thaw" "yxTEMP" "") ; if the layer is frozen
) ;_ progn
) ;_ if
(command "_.layer" "M" "yxTEMP" "")
(command "_.layer" "P" "N" "yxTEMP" "")
(command "_.layer" "C" "2" "yxTEMP" "")
(command "_.color" "ByLayer")

;; New layer, WALL-FINISH
(command "_.layer" "M" "WALL-FINISH" "")
(command "_.layer" "C" "4" "WALL-FINISH" "")
(command "_.color" "ByLayer")

;; New layer, ROUGH-OUTLINE
(command "_.layer" "M" "ROUGH-OUTLINE" "")
(command "_.layer" "C" "223" "ROUGH-OUTLINE" "")
(command "_.color" "ByLayer")

(setvar "clayer" "0")

 

;; SUB-FUNCTION: dtr, Degrees to Radians ;;
(defun dtr (x) ; define degrees to radians function
(* pi (/ x 180.0)) ; (angle / 180) * PI
) ;_ end of dtr


;; FUNCTION: yxML.lsp
(defun c:yxML (/ pt1 pt2 pt3 pt4 pt5 pt6 pt7 pt8 pt9 pt10 pt11 pt12)
; local variables
(yxERR)
(setvar "osmode" (+ 1 32)) ; snaps to ENDpoint and INTersection
(setvar "orthomode" 1) ; 1=on

;; command to check if UCS is set to World if not restore it
(command "_ucs" "w")

;; Options for different thicknesses of walls
(if (not *dp-yx:wt*)
(setq *dp-yx:wt* 0.10) ; default prompt: wall thickness
) ;_ if
(setq
yx:wt (getreal
(strcat "\n Thickness of wall (in meter): <"
(rtos *dp-yx:wt* 2 2)
">: "
)
)
)
(if (not yx:wt)
(setq yx:wt *dp-yx:wt*)
(setq *dp-yx:wt* yx:wt)
) ;_ if

;; Line offset settings
(setq yxTEMP-Offset 0.000) ; offset, on center
(setq ROUGH-Offset (/ yx:wt 2.0)) ; offset, on each side
(setq WALL-Offset (+ (/ yx:wt 2.0) 0.025)) ; offset, on each side

(setq pt1 (getpoint "\n Pick Starting point: "))

;; while
(while
(if pt1
(progn
(setq pt2 (getpoint pt1 "\n Pick Ending point: "))
(if pt2
(progn
(setq ang (angle pt1 pt2)
;; for yxTEMP on center
pt3 (polar pt2 (+ ang (dtr 90.0)) yxTEMP-Offset)
pt4 (polar pt1 (+ ang (dtr 90.0)) yxTEMP-Offset)
;; for ROUGH-OUTLINE (one side)
pt5 (polar pt2 (+ ang (dtr 90.0)) ROUGH-Offset)
pt6 (polar pt1 (+ ang (dtr 90.0)) ROUGH-Offset)
;; for WALL-FINISH (one side)
pt7 (polar pt2 (+ ang (dtr 90.0)) WALL-Offset)
pt8 (polar pt1 (+ ang (dtr 90.0)) WALL-Offset)
;; for ROUGH-OUTLINE (other side)
pt9 (polar pt2 (+ ang (dtr 90.0)) (- ROUGH-Offset))
pt10 (polar pt1 (+ ang (dtr 90.0)) (- ROUGH-Offset))
;; for WALL-FINISH (other side)
pt11 (polar pt2 (+ ang (dtr 90.0)) (- WALL-Offset))
pt12 (polar pt1 (+ ang (dtr 90.0)) (- WALL-Offset))
) ;_ setq

;; Make the line offset 1 unit from point
;; yxTEMP on center
(entmake (list
(cons 0 "LINE")
(cons 10 pt3) ; start point
(cons 11 pt4) ; end point
(cons 8 "yxTEMP") ; new layer
) ;_ list
) ;_ entmake

;; ROUGH-OUTLINE (one side)
(entmake (list
(cons 0 "LINE")
(cons 10 pt5)
(cons 11 pt6)
(cons 8 "ROUGH-OUTLINE")
) ;_ list
) ;_ entmake

;; WALL-FINISH (one side)
(entmake (list
(cons 0 "LINE")
(cons 10 pt7)
(cons 11 pt8)
(cons 8 "WALL-FINISH")
) ;_ list
) ;_ entmake

;; ROUGH-OUTLINE (other side)
(entmake (list
(cons 0 "LINE")
(cons 10 pt9)
(cons 11 pt10)
(cons 8 "ROUGH-OUTLINE")
) ;_ list
) ;_ entmake

;; WALL-FINISH (other side)
(entmake (list
(cons 0 "LINE")
(cons 10 pt11)
(cons 11 pt12)
(cons 8 "WALL-FINISH")
) ;_ list
) ;_ entmake

) ;_ 2nd progn
) ;_ 2nd if
) ;_ 1st progn
) ;_ 1st if
(setq pt1
(getpoint ; pt2, put view rubber-band action
"\n Pick other Starting point or press Enter/Esc to Exit: "
)
)
) ;_ while
;;(reset)
(princ)
) ;_ end of

0 Likes