help with lisp to loop through a layer and change it linens to other layer based on it's color

help with lisp to loop through a layer and change it linens to other layer based on it's color

aridzv
Enthusiast Enthusiast
2,577 Views
22 Replies
Message 1 of 23

help with lisp to loop through a layer and change it linens to other layer based on it's color

aridzv
Enthusiast
Enthusiast

Hi.

i'm importing a file from hydraulic calculation software,

and all the lines that represent pipe are in one layer and are different by color.

i'm looking for a lisp that will loop through this layer and will change each line to a different Existing layer based on its color,

For example:

the original layer called "Pipes", and some of the line's color is 140,some are color 112.

i want to change all of those lines of color 140 to an existing layer called DN110,and all of those lines of color 112 to an existing layer called DN75. 

 

Thanks,

Ari

0 Likes
Accepted solutions (2)
2,578 Views
22 Replies
Replies (22)
Message 2 of 23

_Tharwat
Advisor
Advisor

Something like this?

(defun c:clr2lay (/ int sel ent get col lay)
  ;; Tharwat - 12.10.2020				;;
  ;; clr2lay = color to layer.				;;
  ;; Move lines from Pipes layer to separate layers	;;
  (and (setq int -1 sel (ssget "_X" '((0 . "LINE") (8 . "Pipes"))))
       (while (setq int (1+ int) ent (ssname sel int))
         (and (setq get (entget ent)
                    col (cdr (assoc 62 get)))
              (or (and (= col 140) (setq lay "DN110"))
                  (and (= col 112) (setq lay "DN75"))
                  )
              (entmod (append get (list (cons 8 lay) '(62 . 256))))
              )
         )
       )                            
  (princ)
)
0 Likes
Message 3 of 23

pbejse
Mentor
Mentor

@aridzv wrote:

Hi.

For example:

the original layer called "Pipes", and some of the line's color is 140,some are color 112.

i want to change all of those lines of color 140 to an existing layer called DN110,and all of those lines of color 112 to an existing layer called DN75. 

...


 

You need a list of colors and its corresponding layer name  as shown in the code.

 

 

(defun c:colorTolayer (/ Datalist ss f i ent)
  (setq	Datalist ; Color | Layer
	 '((140 . "DN110")
	   (112 . "DN75")
	  )
  )

  (if (setq ss (ssget "_X" '((0 . "LINE") (8 . "Pipes"))))
    (repeat (setq i (sslength ss))
      (setq ent (entget (setq e (ssname ss (setq i (1- i))))))
      (if (setq f (assoc (cdr (assoc 62 ent)) Datalist))
	(entmod (subst (cons 8 (cdr f)) (assoc 8 ent) ent))
      )
    )
  )
  (princ)
)

 

 

 

HTH

 

EDIT: I did not see your post there Tharwat. 😀

You have too much free time in your hands nowadays

 

Nice idea BTW:

'(62 . 256))))

 

Message 4 of 23

_Tharwat
Advisor
Advisor

Thanks buddy, 

Yeah a bit. 😁


 

0 Likes
Message 5 of 23

aridzv
Enthusiast
Enthusiast

first,

 _Tharwat - tanks for the effort.

 

pbejse - your code worked perfectly.

one more question - 

is it possible to add to your code a line that change the color of the objects to color by layer'so it will also assume the destination layer color??

thanks,

ari.

0 Likes
Message 6 of 23

pbejse
Mentor
Mentor
Accepted solution

@aridzv wrote:

is it possible to add to your code a line that change the color of the objects to color by layer'so it will also assume the destination layer color??

 


Sure

(defun c:colorTolayer (/ Datalist ss f i ent)
  (setq	Datalist ; Color | Layer
	 '((140 . "DN110")
	   (112 . "DN75")
	  )
  )

  (if (setq ss (ssget "_X" '((0 . "LINE") (8 . "Pipes"))))
    (repeat (setq i (sslength ss))
      (setq ent (entget (setq e (ssname ss (setq i (1- i))))))
      (if (setq f (assoc (cdr (assoc 62 ent)) Datalist))
	(entmod (append ent (list (cons 8 (cdr f)) '(62 . 256))))
      )
    )
  )
  (princ)
)

HTH

 

BTW: Did you run Tharwat's offering. It does exactlly what you descibe.

 

Give it a try

 

Message 7 of 23

aridzv
Enthusiast
Enthusiast

THANKS!!!!

work perfectly!!!

Ari.

0 Likes
Message 8 of 23

_Tharwat
Advisor
Advisor

@aridzv wrote:

........ that change the color of the objects to color by layer'so it will also assume the destination layer color??


Does not my program do so?

0 Likes
Message 9 of 23

ronjonp
Advisor
Advisor

Here's another for fun 🙂 .. similar to @pbejse but also includes a filter for lines with those two colors assigned.

(defun c:foo (/ l r s)
  ;; RJP » 2020-10-12
  (and (setq
	 s (ssget "_X" '((0 . "LINE") (8 . "Pipes") (-4 . "<OR") (62 . 140) (62 . 112) (-4 . "OR>")))
       )
       (setq l '((140 "DN110") (112 "DN75")))
       (foreach	e (mapcar 'cadr (ssnamex s))
	 (setq r (cadr (assoc (cdr (assoc 62 (setq el (entget e)))) l)))
	 (entmod (append el (list (cons 8 r) '(62 . 256))))
       )
  )
  (princ)
)
0 Likes
Message 10 of 23

pbejse
Mentor
Mentor

@ronjonp wrote:

... but also includes a filter for lines with those two colors assigned.


Might as well use the data list then

(defun c:colorTolayer (/ Datalist ss f i ent)
  (setq	Datalist ; Color | Layer
	 '((140 . "DN110")
	   (112 . "DN75")
	  )
  )
  (if (setq ss (ssget "_X" (append
			 '((0 . "LINE")(8 . "Pipes")(-4 . "<OR"))
			     (mapcar '(lambda (c)(cons 62 c))
				       (mapcar 'car Datalist))
			 '((-4 . "OR>"))))
	    )
    (repeat (setq i (sslength ss))
      (setq ent (entget (setq e (ssname ss (setq i (1- i))))))
      (if (setq f (assoc (cdr (assoc 62 ent)) Datalist))
	(entmod (append ent (list (cons 8 (cdr f)) '(62 . 256))))
      )
    )
  )
  (princ)
)

 

 

 

0 Likes
Message 11 of 23

aridzv
Enthusiast
Enthusiast

is it possible to change those lines to poly lines and assign global width to them?

0 Likes
Message 12 of 23

ronjonp
Advisor
Advisor

@pbejse wrote:

@ronjonp wrote:

... but also includes a filter for lines with those two colors assigned.


Might as well use the data list then

(defun c:colorTolayer (/ Datalist ss f i ent)
  (setq	Datalist ; Color | Layer
	 '((140 . "DN110")
	   (112 . "DN75")
	  )
  )
  (if (setq ss (ssget "_X" (append
			 '((0 . "LINE")(8 . "Pipes")(-4 . "<OR"))
			     (mapcar '(lambda (c)(cons 62 c))
				       (mapcar 'car Datalist))
			 '((-4 . "OR>"))))
	    )
    (repeat (setq i (sslength ss))
      (setq ent (entget (setq e (ssname ss (setq i (1- i))))))
      (if (setq f (assoc (cdr (assoc 62 ent)) Datalist))
	(entmod (append ent (list (cons 8 (cdr f)) '(62 . 256))))
      )
    )
  )
  (princ)
)

 

 

 


@pbejse Very true this makes it a bit more flexible, nice addition. 😎

Since we're filtering the selection prior, no need for your if statement as we'll always have a valid condition. 🍻

(if (setq f (assoc (cdr (assoc 62 ent)) datalist))
  (entmod (append ent (list (cons 8 (cdr f)) '(62 . 256))))
)
;;Could be
(entmod (append ent (list (cons 8 (cdr (assoc (cdr (assoc 62 ent)) datalist))) '(62 . 256))))

 

0 Likes
Message 13 of 23

pbejse
Mentor
Mentor

@ronjonp wrote:
Since we're filtering the selection prior, no need for your if statement as we'll always have a valid condition. 

THAT is very True, even better 👍 . Thats the reason for filtering after all.

 

 

0 Likes
Message 14 of 23

Sea-Haven
Mentor
Mentor

After changing the properties can convert to a pline. As no hint of width could ask at start or in this suggestion it is set to 1.0.

 

(setq ent (entget (setq e (ssname ss (setq i (1- i))))))
(if (setq f (assoc (cdr (assoc 62 ent)) Datalist))
	  (progn
		(entmod (append ent (list (cons 8 (cdr f)) '(62 . 256))))
		(command "pedit" e "y" "w" 1.0 "")
	  )
      )
0 Likes
Message 15 of 23

pbejse
Mentor
Mentor

@aridzv wrote:

is it possible to change those lines to poly lines and assign global width to them?


Sure

(defun c:colorTolayer (/ Datalist ss f i ent) 
(setq Datalist ; Color | Layer | Global Width
	 '((140  "DN110" 2.5) (112  "DN75" 1.5) ;<-- change the values here
	  )
  )
  (if (setq ss (ssget "_X" (append
			 '((0 . "LWPOLYLINE")(8 . "Pipes")(-4 . "<OR"))
			     (mapcar '(lambda (c)(cons 62 c))
				       (mapcar 'car Datalist))
			 '((-4 . "OR>"))))
	    )
    (repeat (setq i (sslength ss))
      (setq ent (entget (setq e (ssname ss (setq i (1- i))))))
      (setq f (assoc (cdr (assoc 62 ent)) Datalist))
	(entmod (append ent
			(mapcar '(lambda (a b)(cons a b))
			  	'(62 8 43) f )'((62 . 256)))
      )
    )
  )
  (princ)
)

HTH

 

This would have not been possible without the support and great ideas from @_Tharwat and @ronjonp. Please donate to WeveGivenEverythingThatWeGot and IWishIcouldWriteACodeLikeThat Foundation. 😉

 

 

0 Likes
Message 16 of 23

pbejse
Mentor
Mentor

@Sea-Haven wrote:

After changing the properties can convert to a pline. As no hint of width could ask at start or in this suggestion it is set to 1.0.


Oh, its that what it is, Change the object to Plines ?  I guess you're right. Back to the drawing board. 

Good catch.

 

(defun c:colorTolayer (/ Datalist ss f i ent eData) 
(setq Datalist ; Color | Layer | Global Width
	 '((140  "DN110" 2.5) (112  "DN75" 1.5)
	  )
  )
(setvar 'CECOLOR "BYLAYER")
  
  (if (setq ss (ssget "_X" (append
			 '((0 . "LINE")(8 . "Pipes")(-4 . "<OR"))
			     (mapcar '(lambda (c)(cons 62 c))
				       (mapcar 'car Datalist))
			 '((-4 . "OR>"))))
	    )
    (repeat (setq i (sslength ss))
      (setq ent (entget (ssname ss (setq i (1- i)))))
      (setq eData (mapcar '(lambda (d)
		 	(Cdr (assoc d ent))) '(62 10 11)))	
      
      (setq f (assoc (Car edata) Datalist))
(entdel e) (entmakex (append (list (cons 0 "LWPOLYLINE") (cons 100 "AcDbEntity") (cons 100 "AcDbPolyline") (cons 90 (length (Cdr eData))) (cons 70 0) (cons 8 (cadr f)) (cons 43 (caddr f)) ) (mapcar (function (lambda (p) (cons 10 p))) (Cdr eData))) ) ) ) (princ) )

HTH

 

This would have not been possible without the support and great ideas from @_Tharwat and @ronjonp. and @Sea-Haven Please donate to WeveGivenEverythingThatWeGot and IWishIcouldWriteACodeLikeThat and IShouldveReadTheRequestThroroughly Foundation. 

😉😉

 

 

 

0 Likes
Message 17 of 23

Sea-Haven
Mentor
Mentor

The request was very vauge hence very simple answer. Entmakex a better answer than pedit.

0 Likes
Message 18 of 23

aridzv
Enthusiast
Enthusiast
 

 first  - many thanks!!

 
 

 the routine to change the lines to polylines don't work for some reason..

it make no effect on the lines,

not changing them to the target layer, and not changing them to polylines.

maybe the filtering routine is the blame?

thanks,

Ari.

0 Likes
Message 19 of 23

pbejse
Mentor
Mentor

@aridzv wrote:

it make no effect on the lines,

not changing them to the target layer, and not changing them to polylines.

 


Think its time that you post a sample drawing. show a couple of lines 10 would be enough, remove all the confidential stuff and we pick up from there. preferably the file where you said the code has no effect on the lines.

 

There are two codes posted. one that is filtered for LWPOLYLINE and the other as LINE, which one did you try? two different approach.

 

 

 

0 Likes
Message 20 of 23

aridzv
Enthusiast
Enthusiast

you are right!

here are 2 files:

1. dwg drawing with the source drawing,a legend of the new lines and all the necessary layers.

2. the modified LSP file with all the layers names (to save work..)

 

Thanks,

Ari. 

0 Likes