layer change

layer change

HR2323
Advocate Advocate
2,157 Views
23 Replies
Message 1 of 24

layer change

HR2323
Advocate
Advocate

hi every one,

 Please help us, I am trying to layer the box and title in several drawing.

Bring the outer of the box into the layer and also want the title of the drawing in another layer as well. Each drawing has a name similar to the title.

0 Likes
Accepted solutions (3)
2,158 Views
23 Replies
Replies (23)
Message 2 of 24

pbejse
Mentor
Mentor

@HR2323 wrote:

hi every one,

 Please help us, I am trying to layer the box and title in several drawing.

Bring the outer of the box into the layer and also want the title of the drawing in another layer as well. ...


Quick question:

Where are these objects located? Model or Layout tab?

Model tab: could be anywhere , any scale 

Layout tab: Always same position (0.0 0.0) for the outer of the box lower left coordinates? 

 

You guys use Autoscript or ScriptPro? 

 

 

 

0 Likes
Message 3 of 24

HR2323
Advocate
Advocate

Hi @pbejse,

Yes all drawing is in model space, the box size can be in any scale and can be anywhere. i have never use script!

0 Likes
Message 4 of 24

HR2323
Advocate
Advocate
I know this is not difficult. But doesn't anyone want to do it?
0 Likes
Message 5 of 24

pbejse
Mentor
Mentor

@HR2323 wrote:
I know this is not difficult. But doesn't anyone want to do it?

 

Its not that, its just too little information, too many variables to consider with the conditions you outline on your request, you need to give us more to work with, not just a random LWPOLYLINE and a TEXT. Coding is about efficiency, 

 

Post a better sample drawing, the worst you can find then we will pick up from there.

 

 

0 Likes
Message 6 of 24

Moshe-A
Mentor
Mentor

@HR2323  hi,

 

Here is my 'small' contribution to this 'project' 😎

 

Command LTASK starts by selecting all text,mtexts and all closed polylines with 4 points

then scan for polylines with equal diagonals fetch the largest one and send it to "mbox" layer.

then scan for texts value and find the one in question and send it to "Dwg Name" layer.

 

now all you got left, is to learn how to use >> script pro <<  and you are done 😁

 

so easy ha? 😜

Moshe

 

 

 

; Layer Task
(defun c:LTASK (/ split_ss gen_sorted_areas change_layer ;local functions
                  ss0 ss1 ss2 areas elist text)

 (defun split_ss (/ elist)
  (setq ss1 (ssadd) ss2 (ssadd))

  (foreach ename (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss0)))
   (setq elist (entget ename)) 
   (if (eq (cdr (assoc '0 elist)) "LWPOLYLINE")
    (ssadd ename ss1)
    (ssadd ename ss2)
   )
  ); foreach  
 ); split_ss
  
 ; generate sorted list by areas 
 (defun gen_sorted_areas (/ geometric eq_diag ;| local functions |;)

  ; return polyline 4 points 
  (defun geometric (ent)
   (mapcar
    '(lambda (i)
     (vlax-curve-getPointAtParam ent i)
    )
    '(0 1 2 3)
   ); mapcar
  ); geometric
  
  ; is diagonals equal? 
  (defun eq_diag (l)
   (equal (distance (car  l) (caddr  l))
          (distance (cadr l) (cadddr l)) 1e-3) ; fuzz is 0.001
  ); eq_diag

  ; here start gen_sorted_areas
  (vl-sort
   (vl-remove-if
    'not
    (mapcar
     '(lambda (ename)
       (if (eq_diag (geometric ename))
        (cons (vlax-curve-getArea ename) ename)
       )
      ); lambda
     (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss1)))
    ); mapcar
   ); vl-remove-if 
   '(lambda (a0 a1) (> (car a0) (car a1)))
  ); vl-sort 
 ); gen_sorted_areas

 (defun change_layer (lay ent)
  (if (null (tblsearch "layer" lay))
   (command "._layer" "_n" lay "")
  )

  (command "._chprop" "_si" ent "_Layer" lay "")
 ); change_layer
  
 ; here start c:LTASK
 (setvar "cmdecho" 0)
 (command "._undo" "_begin")
  
 (if (setq ss0 (ssget "_x" '((-4 . "<or")
                              (0 . "text,mtext")
                              (-4 . "<and") (0 . "lwpolyline") (90 . 4) (70 . 1) (-4 . "and>")
                             (-4 . "or>"))
               )
     )
  (progn
   (split_ss)
   
   (setq areas (gen_sorted_areas))
   (change_layer "mbox" (cdar areas))
   
   (foreach ename (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss2)))
    (setq elist (entget ename))
    (setq text (cdr (assoc '1 elist)))
    (if (wcmatch (strcase text) "DRAWING_NUMBER-*")
     (change_layer "Dwg Name" ename) 
    ); if
   ); foreach
   
   (princ "\nSuccessfully done.") 
  ); progn
 ); if

 (command "._undo" "_end")
 (setvar "cmdecho" 1)

 (princ)  
); c:LTASK

 

 

0 Likes
Message 7 of 24

pbejse
Mentor
Mentor

@Moshe-A wrote:

Here is my 'small' contribution to this 'project' 😎

 

Might as well play

 

(defun c:demo ( / TargetObjects i e LPolyColl TxtColl TextInside TextisInside)
  (if
      (setq  LPolyColl nil TxtColl nil	      
	      TargetObjects  (ssget "_X" (append
	       '((410 . "Model")(-4 . "<OR") (-4 . "<AND")
		  (0 . "LWPOLYLINE") (90 . 4)  (-4 . "&=")
		  (70 . 1)
		  (-4 . "AND>")
		  (-4 . "<AND")
		  (0 . "TEXT")
		)
		 (list (setq dwgText (cons  1 (vl-filename-base (getvar 'dwgname)))))
		 '((-4 . "AND>")(-4 . "OR>"))
		 		)
			)
	)
	(progn
	  (repeat (setq i (sslength TargetObjects))
	    (setq e (ssname TargetObjects (setq i (1- i))))
	    (if	(eq (cdr (assoc 0 (entget e))) "LWPOLYLINE")
	      (setq LPolyColl (cons (list e (mapcar 'cdr
			(vl-remove-if-not '(lambda ( x ) (= 10 (car x))) (entget e))) (vlax-curve-getArea e))
					  LPolyColl))
	      (setq TxtColl (cons e TxtColl))
	    )
	  )
	  (vl-some '(lambda (pl)
		      (if (and
			    (setq TextInside (ssget "_CP" (cadr pl) (list '(0 . "TEXT") dwgText)))
			      (setq TextisInside(Vl-some '(lambda (st)
					  		(ssmemb st TextInside)) TxtColl))
			    )
			(progn
			  (entmod (append (entget (Car pl))'((8 . "MBOX")) ))
			  (entmod (append (entget TextisInside)'((8 . "Dwg Name"))))
			  (princ "\n Boundary and Drawing name found")
			  )
			)
		      ) (vl-sort LPolyColl '(lambda (a b)
					      (> (caddr a)(caddr b))))
		   )
	  )
    )(princ)
  )

 

How it works:

Search for LWPLOLYINE and TEXT [assuming string as drawing name without extension ] <--- Take note of this

Sort the LWPolyines [ that fits the criteria ] from the largest to smallest

TEXT is inside Lwpolyline

Both condition are met, the layers will be assigned.

 

HTH 

 

EDIT: Would be loads easier if the OP just post a sample drawing that shows the actual condition. such as what is the  criteria for Drawing number string content.

 

0 Likes
Message 8 of 24

Moshe-A
Mentor
Mentor

@HR2323 ,

 

made some fine tuning 

 

1. select objects only in model space.

2. secure the check for polylines eliminating any other 4 points polylines that are not a true rectangle.

    i know you think there are no other shapes of polylines in my drawings but you never can be sure 😀

 

enjoy

moshe

 

0 Likes
Message 9 of 24

HR2323
Advocate
Advocate

Hi @Moshe-A, @pbejse ,

  Thank you both of you for the giving code, the Lisp code is working properly on post number 6 as I expected but still it is not working on some drawing, it is not putting all the outer box in the layer, It brings all the text into the layer but the text should only be selected inside the box.

 

 

0 Likes
Message 10 of 24

pbejse
Mentor
Mentor
Accepted solution

@HR2323 wrote:

it is not putting all the outer box in the layer, It brings all the text into the layer but the text should only be selected inside the box.


Two things:

  • I'm tryingto put intelligence into the code by not hardcoding the "DRAWING_NUMBER-##" string but instead feeding the drawing name as a filter.
  • You never did mention that there are multiple sheets

I guess i'll need to dumb it down a little just to work on your sample.

 

Will there be any more surprises? Like multiple scales in one drawing? We asked you repeatedly to provide a  real life scenario [ like an actual drawing name etc.. ] that way you don't leave members here guessing while you wait for one that works.

 

EDIT: You sample is too easy. We need a more complex sample drawing. one that shows a name that we can use as filters or even one wiht different scales

 

 

(defun c:demo ( / TargetObjects i e LPolyColl TxtColl TextInside TextisInside)
  (if
      (setq  LPolyColl nil TxtColl nil	      
	      TargetObjects  (ssget "_X" (append
	       '((410 . "Model")(-4 . "<OR") (-4 . "<AND")
		  (0 . "LWPOLYLINE") (90 . 4)  (-4 . "&=")
		  (70 . 1)
		  (-4 . "AND>")
		  (-4 . "<AND")
		  (0 . "TEXT")
		  (1 . "DRAWING_NUMBER-*")
		  (-4 . "AND>")(-4 . "OR>"))
		 		)
			)
	)
	(progn
	  (repeat (setq i (sslength TargetObjects))
	    (setq e (ssname TargetObjects (setq i (1- i))))
	    (if	(eq (cdr (assoc 0 (entget e))) "LWPOLYLINE")
	      (setq LPolyColl (cons (list e (mapcar 'cdr
			(vl-remove-if-not '(lambda ( x ) (= 10 (car x))) (entget e))) (vlax-curve-getArea e))
					  LPolyColl))
	      (setq TxtColl (cons e TxtColl))
	    )
	  )
	  (setq LPolyColl (vl-sort LPolyColl '(lambda (a b)
					      (> (caddr a)(caddr b)))))
	
	(while (and
		 (setq pl (car LPolyColl)) TxtColl )
	  (if
	    (and
		(setq TextInside (ssget "_CP" (cadr pl) '((0 . "TEXT")(1 . "DRAWING_NUMBER-*"))))		
		(setq TextisInside(Vl-some '(lambda (st)
					      (ssmemb st TextInside)) TxtColl))
		)
		(progn
		  (entmod (append (entget (Car pl))'((8 . "MBOX")(62 . 4)) ))
		  (entmod (append (entget TextisInside)'((8 . "Dwg Name")(62 . 4))))
		  (setq TxtColl (vl-remove TextisInside TxtColl))
		  (princ (strcat "\n Boundary and Drawing " (Cdr (assoc 1 (entget TextisInside)))  " name found"))
		  )
		)
	  (setq LPolyColl (Cdr LPolyColl))
	      ) 
	   )
	  )
    (princ)
  )

 

ADD color cyan for visualization

 

 

 

 

0 Likes
Message 11 of 24

HR2323
Advocate
Advocate

@pbejse,

  I was having difficulty clarifying a little bit, which is why I delayed the replay, I am not feeling the need to do any more updates at the moment, it is working fine now. Thank you for your support.

 

Thank you very much

0 Likes
Message 12 of 24

pbejse
Mentor
Mentor

@HR2323 wrote:

...I am not feeling the need to do any more updates at the moment, it is working fine now. Thank you for your support.


 

OK then. Reply to this thread if you need more help with this program in the future.

You are welcome.

 

pBe

 

0 Likes
Message 13 of 24

HR2323
Advocate
Advocate

Hi @pbejse ,

 

I have noticed one more thing that it applies only to objects appearing in front of the screen. While this should also be applied to all outer boxes that are visible on the screen or not.

 

0 Likes
Message 14 of 24

pbejse
Mentor
Mentor

@HR2323 wrote:

Hi @pbejse ,

 

I have noticed one more thing that it applies only to objects appearing in front of the screen. While this should also be applied to all outer boxes that are visible on the screen or not.

 


No worries, see attached lisp.

Command:  MboxandName

 

 

 

0 Likes
Message 15 of 24

HR2323
Advocate
Advocate

@pbejse,

 Once again thank you now it is working properly well.👍
  Have a good day😀

0 Likes
Message 16 of 24

pbejse
Mentor
Mentor

@HR2323 wrote:

@pbejse,

 Once again thank you now it is working properly well.👍
  Have a good day😀


Good for you,

One thing though: Change this..

(append
  	'((0 . "TEXT")(1 . "DRAWING_NUMBER-*")(-4 . ">=,>=,*"))
       (list (cons 10 ll)
	     '(-4 . "<=,<=,*")
	     (cons 10 ur)
       		)
       )

To include filter for "Model" space only

(append
       '((0 . "TEXT")(1 . "DRAWING_NUMBER-*")(410 . "Model")(-4 . ">=,>=,*"))
       (list (cons 10 ll)
	     '(-4 . "<=,<=,*")
	     (cons 10 ur)
       		)
       )

Cheers

 

 

 

0 Likes
Message 17 of 24

HR2323
Advocate
Advocate

@pbejse @

Thanks to the update another small update will be required, manually typing the drawing text "DRAWING_NUMBER-*" in command line.

0 Likes
Message 18 of 24

pbejse
Mentor
Mentor

@HR2323 wrote:

@pbejse @

Thanks to the update another small update will be required, manually typing the drawing text "DRAWING_NUMBER-*" in command line.


 

There are at least three ways to do this

  1. Based the filter on the drawing name
  2. Select a TEXT object as reference, removing sequence number at the end of the string , i.e one of the target drawing number.  
  3. Type the drawing number string at command prompt.

 

Pick one... 

 

 

 

0 Likes
Message 19 of 24

HR2323
Advocate
Advocate

@pbejse 

Second option will be go, I think that would be nice.

0 Likes
Message 20 of 24

pbejse
Mentor
Mentor
Accepted solution

@HR2323 wrote:

@pbejse 

Second option will be go, I think that would be nice.


 

This is going to be the last one  for you @HR2323 

 

Use either select a text object or Type I to enter string

Command: MBOXANDNAME
Select Text/I for input: [ USER SELECT TEXT OBJECT ON SCREEN ]
 Boundary and Drawing DRAWING_NUMBER-27 name found
 Boundary and Drawing DRAWING_NUMBER-23 name found
 Boundary and Drawing DRAWING_NUMBER-01 name found
------------------------------------------------------------------
Command: MBOXANDNAME
Select Text/I for input: I [ USER TYPED "I" ]
Enter Drawing Number: DRAWING_NUMBER <-- NO NEED FOR INCLUDE "*" [ USER ENTER STRING TO SEARCH ] 
 Boundary and Drawing DRAWING_NUMBER-27 name found
 Boundary and Drawing DRAWING_NUMBER-23 name found
 Boundary and Drawing DRAWING_NUMBER-01 name found

HTH

 

0 Likes