Send Wipeout to Back

Send Wipeout to Back

ChaitanyaHeb
Advocate Advocate
1,751 Views
17 Replies
Message 1 of 18

Send Wipeout to Back

ChaitanyaHeb
Advocate
Advocate

Hello Everyone,

 

I have code that retrieves blocks from the master drawing. I added wipeout to all my blocks in the master file and sent it back using draworder command. Now in the current drawing when I call any block wipeout is at the top and hiding all the entities behind it.

So I have been trying to figure this out with several approaches and need some help. 

I would like to send all Wipeouts back when the block is getting retrieved from the master file.

Can anyone look into the code and guide what lines need to be added so that every time I place the block in the current drawing wipeout is back.


=========================Get Device.lsp=========================

(defun c:GetBlock (/ *error* dbx doc dwg userpath)
(vl-load-com)

;; Error handling function
(defun *error* (msg)
(if (and (= 'vla-object (type dbx)) (not (vlax-object-released-p dbx)))
(vlax-release-object dbx)
)
(if (and msg (not (wcmatch (strcase msg t) "*break,*cancel*,*exit*")))
(princ (strcat "\nError: " msg))
)
(princ)
)

;; Get the current user's profile path
(setq userpath (getenv "USERPROFILE"))

;; Construct the dynamic path to the source file
(setq dwg (strcat userpath "\\AppData\\Roaming\\Autodesk\\ApplicationPlugins\\Master.dwg"))

;; Debugging: Print constructed path
(princ (strcat "\nConstructed Path: " dwg))

;; Check if the file exists
(if (not (findfile dwg))
(progn
(princ (strcat "\nFile not found: " dwg))
(exit) ; Exit the function if file not found
)
)

;; Proceed if file exists
(cond
((not (setq dbx (LM:GetDocumentObject dwg)))
(princ "\nUnable to interface with the selected drawing.")
)
(t
(prompt "\nEnter block name to insert from source drawing: ")
(setq blockName (getstring "\nBlock Name: "))

(if (not (LM:InsertBlockFromSource dbx blockName))
(princ (strcat "\nBlock \"" blockName "\" not found in the source drawing."))
(princ (strcat "\nBlock \"" blockName "\" inserted successfully."))
)
)
)
(princ)
)

;; Get Document Object - Lee Mac
(defun LM:GetDocumentObject (dwg / app dbx dwl vrs)
(cond
((not (setq dwg (findfile dwg)))
(princ (strcat "\nFile not found in LM:GetDocumentObject: " dwg))
nil
)
((cdr
(assoc (strcase dwg)
(vlax-for doc (vla-get-documents (setq app (vlax-get-acad-object)))
(setq dwl (cons (cons (strcase (vla-get-fullname doc)) doc) dwl))
)
)
)
)
((progn
(setq dbx
(vl-catch-all-apply 'vla-getinterfaceobject
(list app
(if (< (setq vrs (atoi (getvar 'acadver))) 16)
"objectdbx.axdbdocument" (strcat "objectdbx.axdbdocument." (itoa vrs))
)
)
)
)
(or (null dbx) (vl-catch-all-error-p dbx))
)
(prompt "\nUnable to interface with ObjectDBX.")
)
((not (vl-catch-all-error-p (vl-catch-all-apply 'vla-open (list dbx dwg))))
dbx
)
)
)

;; Function to insert block from source drawing
(defun LM:InsertBlockFromSource (dbx blockName)
(if (not (LM:getitem (vla-get-blocks dbx) blockName))
nil
(progn
(setq doc (vla-get-activedocument (vlax-get-acad-object)))
(if (not (vl-catch-all-error-p
(vl-catch-all-apply 'vlax-invoke
(list dbx 'copyobjects
(list (LM:getitem (vla-get-blocks dbx) blockName))
(vla-get-blocks doc)
)
)
)
)
(progn
(if (LM:getitem (vla-get-blocks doc) blockName)
(LM:InsertBlockAtPoint doc blockName)
nil
)
)
nil
)
)
)
)

;; Function to insert block at a user-specified insertion point
(defun LM:InsertBlockAtPoint (doc blockName)
(while (setq insPt (getpoint "\nSpecify insertion point: "))
(vla-insertblock
(vlax-get-property doc (if (= 1 (getvar 'cvport)) 'paperspace 'modelspace))
(vlax-3D-point insPt)
blockName
1.0 1.0 1.0
0
)
)
)

;; VLA-Collection: Get Item - Lee Mac
(defun LM:getitem (col idx / obj)
(if (not (vl-catch-all-error-p (setq obj (vl-catch-all-apply 'vla-item (list col idx)))))
obj
)
)

(princ)

0 Likes
Accepted solutions (1)
1,752 Views
17 Replies
Replies (17)
Message 2 of 18

stev98312
Enthusiast
Enthusiast

This sends ALL wipeouts to back.

 

(sssetfirst nil (ssget "_X" '((0 . "WIPEOUT"))))(command "_.draworder" "_b")

 

 

Steve

0 Likes
Message 3 of 18

ChaitanyaHeb
Advocate
Advocate

Hi Steve,

 

Can you suggest where this line should be placed so that it will be more efficient?

0 Likes
Message 4 of 18

ChaitanyaHeb
Advocate
Advocate

@paullimapa@Sea-Haven
Can you please take a look at this and help in finding the solution?

0 Likes
Message 5 of 18

paullimapa
Mentor
Mentor
0 Likes
Message 6 of 18

ChaitanyaHeb
Advocate
Advocate

@paullimapa Sorry for the late reply. 
As you mentioned I went through the thread and extracted the lines. I tested those lines which are working fine. However, integrating or merging it with the upper code does not work as expected. I have attached both codes (Code lines extracted from thread and Code lines merged with original code). Please take a look and let me know what exactly I am missing.

0 Likes
Message 7 of 18

paullimapa
Mentor
Mentor

could you also share a sample dwg that contains a couple of blocks that have wipeouts that you want to send to back


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 8 of 18

ChaitanyaHeb
Advocate
Advocate

@paullimapa 
In this master dwg file wipeout is back but when the same blocks are retrieved into another drawing wipeout comes to the front of nowhere and I don't know why. Along with the solution please help me understand the problem.

Thanks,

Chaitanya H

0 Likes
Message 9 of 18

CodeDing
Mentor
Mentor

@ChaitanyaHeb ,


@ChaitanyaHeb wrote:

I have code that retrieves blocks from the master drawing. I added wipeout to all my blocks in the master file and sent it back using draworder command. Now in the current drawing when I call any block wipeout is at the top and hiding all the entities behind it.


 

I have had this issue before. For me, I found that the display of the Wipeout will appear based on the ENTITY CREATION ORDER when you make the block.

 

For example, if you create a block in this order:

1) Create Rectangle

2) Add text over rectangle

3) Add wipeout to rectangle (then send to back)

 

...then you will see the issue you describe.

 

To fix it...

1) Edit your block in block editor.

2) copy all of the entities EXCEPT for the Wipeout(s) from a basepoint (0,0,0) (make sure you're using COPYBASE command, or Ctrl+Shift+C, do NOT use COPY command)

3) after copying, delete all of the entities EXCEPT the Wipeout(s)

4) Paste the copied entities back at their base point (0,0,0)

 

...OR, create your block in this order:

1) Add wipeout

2) Create Rectangle

3) Add text over rectangle

 

Hope that helps!

Best,

~DD

0 Likes
Message 10 of 18

ChaitanyaHeb
Advocate
Advocate

@CodeDing 
Exactly like you described I added the wipeout after attributes and actions were added to the block. But the steps you mentioned to follow is going to eat big chunk of my time as I have to repeat this for at least 100+ blocks.



Regards,
Chaitanya H

0 Likes
Message 11 of 18

paullimapa
Mentor
Mentor

I found where your code failed.

Basically since the function LM:SendWipeoutBack inside your GetBlock1903.lsp does NOT successfully send the Wipeout inside the Block to the back, don't use that. Instead I took WTB.lsp from the thread I gave you which does work, modified it and then included that as part of your code.

Re: Send Wipeout to Back of Draworder within Block Definition - Autodesk Community

These are the problem areas I found in your original GetBlock1903.lsp code:

1. Does this ADTFireAlarmMaster.dwg drawing exist since you provided for me Master.dwg instead?

 

  ;; Construct the dynamic path to the source file
  (setq dwg (strcat userpath "\\AppData\\Roaming\\Autodesk\\ApplicationPlugins\\UKDesignCUI\\ConfigDwg\\ADTFireAlarmMaster.dwg"))

 

2. Inside the LM:InsertBlockAtPoint function you wanted to call this LM:SendWipeoutBack subfunction passing it the blk argument:

 

;; Function to insert block at a user-specified insertion point
(defun LM:InsertBlockAtPoint (doc blockName)
  (while (setq insPt (getpoint "\nSpecify insertion point: "))
    (vla-insertblock
      (vlax-get-property doc (if (= 1 (getvar 'cvport)) 'paperspace 'modelspace))
      (vlax-3D-point insPt)
      blockName
      1.0 1.0 1.0
      0
    )
    (LM:SendWipeoutBack blk) 
)

 

 First problem here is what is blk variable set equal to?

Second of all the LM:SendWipeoutBack function has no arguments but only declaration of local variables with one of them that happens to be blk:

 

;; Function to move wipeouts to the back after insertion
(defun LM:SendWipeoutBack (/ blk wipeouts)

 

3. As I stated at the beginning since LM:SendWipeoutBack doesn't work I changed it to call the c:wtb function:

 

;; Function to insert block at a user-specified insertion point
(defun LM:InsertBlockAtPoint (doc blockName)
  (while (setq insPt (getpoint "\nSpecify insertion point: "))
    (vla-insertblock
      (vlax-get-property doc (if (= 1 (getvar 'cvport)) 'paperspace 'modelspace))
      (vlax-3D-point insPt)
      blockName
      1.0 1.0 1.0
      0
    )
;    (LM:SendWipeoutBack blk) ; this function has no arguments & currently does not work
    (c:wtb) ; this function modified from C:WTB works
  )
)

 

Here are the changes I made to the WTB.lsp function so instead of requesting for a Block selection it'll automatically select the last Block inserted:

 

(defun c:WTB ( / s )
;    (princ "\nSelect Block: ")
    (if ; (setq s (ssget "_+.:E:S" '((0 . "INSERT"))))
     (not(vl-catch-all-error-p (vl-catch-all-apply 'vla-get-effectivename (list (vlax-ename->vla-object (entlast))))))   
     (progn
			(LM:ApplytoBlockObjects ;this one targets the parent block
				(vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))
;				(vla-get-effectivename (vlax-ename->vla-object (ssname s 0)))
				(vla-get-effectivename (vlax-ename->vla-object (entlast)))
			   '(lambda ( obj ) (if (= "AcDbWipeout" (vlax-get obj 'objectname)) (LM:movetobottom (list obj))))
			);end of 1st LM:Apply
			(LM:ApplytoBlockObjects ;this one targets the annoyonmous block
				(vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))
;				(vla-get-name (vlax-ename->vla-object (ssname s 0)))
				(vla-get-effectivename (vlax-ename->vla-object (entlast)))
			   '(lambda ( obj ) (if (= "AcDbWipeout" (vlax-get obj 'objectname)) (LM:movetobottom (list obj))))
			);end of 2nd LM:Apply
		);end of progn
    (princ"\nLast Object is NOT a Block")  
	);end of if
    (command "regenall")
    (princ)
);end of defun

 

I also commented out the following princ statements:

 

;(princ (strcat "\n:: WipeoutBlockToBack.lsp | Version 1 | Brandon Gum "
;"\n:: Available Command:"
;"\n::    \"WTB\" - Send block's wipeout to back"
;);end of strcat
;);end of princ
;(princ);surpress additional output

 

Lastly, after combining the code I found a total of 3 LM:safearrayvariant functions that are exactly the same:

 

(defun LM:safearrayvariant ( typ lst )
    (vlax-make-variant
        (vlax-safearray-fill
            (vlax-make-safearray typ (cons 0 (1- (length lst))))
            lst
        )
    )
)

 

After commenting out two of them, now your modified GetBlock1903.lsp(attached) works.

 


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
Message 12 of 18

ChaitanyaHeb
Advocate
Advocate

@paullimapa 
Please see the reply as well as I have a small doubt listed

1. Does this ADTFireAlarmMaster.dwg drawing exist since you provided for me Master.dwg instead?
CH---> Yes the file exists in the path provided. Further, the shared .dwg here was the test.

2. Inside the LM:InsertBlockAtPoint function you wanted to call this LM:SendWipeoutBack subfunction passing it the blk argument:

First problem here is what is blk variable set equal to?

Second of all the LM:SendWipeoutBack function has no arguments but only declaration of local variables with one of them that happens to be blk:
CH---> I am not a complete developer. I have just started to learn lisp. This code I developed with the help of AI and also by taking Lee-Mac website help.

My Doubt:

As you have commented out “(LM:SendWipeoutBack blk)” under the section “LM:InsertBlockAtPoint” part shall I delete the lines related to “LM:SendWipeoutBack” which is appearing twice.

The reason is I want to keep the code structure clean and remove the code parts that are not required. For reference, I have attached snips.

ChaitanyaHeb_0-1738045274594.png

 

ChaitanyaHeb_1-1738045365177.png

 




0 Likes
Message 13 of 18

paullimapa
Mentor
Mentor
Accepted solution

AI is not there yet to provide proper LISP code so I would avoid the use of AI.

Yes, any function you're not using in the code can be removed.

I've attached a cleaner version.


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 14 of 18

ChaitanyaHeb
Advocate
Advocate

@paullimapa 
Thank you. You helped me a lot in debugging this code. 
I agree relying on AI completely is not a good practice for a beginner like me and Yes AI is not there yet to think completely like a human.

Regards
Chaitanya Hebliakr

0 Likes
Message 15 of 18

paullimapa
Mentor
Mentor

you are welcome...cheers!!!


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 16 of 18

ChaitanyaHeb
Advocate
Advocate

@paullimapa 

Thank You.

You helped me a lot in debugging this code.
Yes, I agree relying completely on AI is not good practice for a beginner like me and also like you said AI is not there yet to think like humans and provide solutions.

Regards,

Chaitanya Heblikar

0 Likes
Message 17 of 18

Ate1964
Observer
Observer

it seems to me that this effort to put wipout's on the back, is the wrong way to turn them of ??

they are meant to be on top to simplify a block, correct?

so i put them all on a layer wipeout and turn that layer on or of depending if i want to see details or not.

any better ideas ?

 

i would like to switch that lsp to move wipeout to front ! 🙂

0 Likes
Message 18 of 18

Ate1964
Observer
Observer

i would like to switch that lsp to move wipeout to front !

0 Likes