Author Topic: Changing anonymous block with another block  (Read 5053 times)

0 Members and 1 Guest are viewing this topic.

Rabbit

  • Guest
Changing anonymous block with another block
« on: October 21, 2014, 11:49:56 AM »
I've spent way more time that necessary trying to figure out how to do it.  My biggest obstacle is just getting the anonymous blocks and then processing them to make sure they are the correct block.

Here's the situation:  In my drawing template, I have a dynamic block, it's name is "DaBlock".  This block is going to change in future version, but, I need for my lisp routines to handle this block in a legacy fashion.  So, my idea is to look at the name of stretch parameters find the one that is called "AFF", which is in the new version of the block.  If "DaBlock" has parameter "AFF", then do this code, otherwise do that code.  Simple.  Nope.  "DaBlock" is an anonymous block.  I cannot for the life of me figure out how to do a SSGET "X" for anonymous block "*UXXXX", when the only thing I have to go by is "DaBlock" 

----hmmmmmm
While writing this, I came up with something, but it doesn't work either because I have a version of "DaBlock" inside of another block.  And, I think entdel is crashing too.  Here's what I tried:

Code - Auto/Visual Lisp: [Select]
  1. (setq xlist (ssget "X" (list (cons 0  "INSERT"))))
  2.       (repeat (setq cnt (1- (sslength xlist)))
  3.         (if (= (vla-Get-EffectiveName (vlax-ename->vla-object (ssname xlist cnt))) "DaBlock" )
  4.           (setq goodset (cons (ssname xlist cnt) goodset))))
  5.  
  6.       (repeat (setq cnt (1- (length goodset)))
  7.         (if (not (assoc "AFF"
  8.                         (mapcar
  9.                           (function (lambda ( _prop ) (cons (vla-get-propertyname _prop) (vlax-get _prop 'Value))))
  10.                           (vlax-invoke (vlax-ename->vla-object (nth cnt goodset)) 'GetDynamicBlockProperties)
  11.                         );mapcar
  12.             ))
  13.           (progn;get insertion points and delete old blocks
  14.             (setq InsPntList (cons (safearray-value (variant-value (vla-get-insertionpoint (vlax-ename->vla-object (nth cnt goodset))))) InsPntList))
  15.             (entdel (nth cnt goodset))
  16.           );progn
  17.         )
  18.         );repeat
  19.  
  20.       (coomand "-purge" "B" "*" "N")
  21.      
  22.       (foreach item InsPntList)
  23.         (command "_insert" "C:\\Folder\\DaBlock.dwg" item 1 1 0.0))
  24.  
  25. ;;;Another obstacle is that the new block and old block have different insertion points.
  26.  
« Last Edit: October 21, 2014, 11:58:03 AM by Rabbit »

danallen

  • Guest
Re: Changing anonymous block with another block
« Reply #1 on: October 21, 2014, 11:55:16 AM »
can't help thinking about daBlock and daBears

GP

  • Newt
  • Posts: 83
  • Vercelli, Italy
Re: Changing anonymous block with another block
« Reply #2 on: October 21, 2014, 11:58:47 AM »
Try:

Code: [Select]
(setq xlist (ssget "_X" (list '(0 . "INSERT") (cons 2 (strcat "`*U*," "DaBlock")))))

ronjonp

  • Needs a day job
  • Posts: 7526
Re: Changing anonymous block with another block
« Reply #3 on: October 21, 2014, 12:10:25 PM »
See if this helps you out. *untested*
Code - Auto/Visual Lisp: [Select]
  1. (defun c:foo (/ e n o pts ss)
  2.   (if (setq ss (ssget "X" (list (cons 0 "INSERT") (cons 2 "dablock,`*U*"))))
  3.     (repeat (setq n (sslength ss))
  4.       (setq o (vlax-ename->vla-object (setq e (ssname ss (setq n (1- n))))))
  5.       (if (= (strcase (vla-get-effectivename o)) "DABLOCK")
  6.         (if (vl-some (function (lambda (_prop) (= "AFF" (strcase (vlax-get _prop 'propertyname)))))
  7.                      (vlax-invoke o 'getdynamicblockproperties)
  8.             )
  9.           (entdel e)
  10.           (setq pts (cons (vlax-get o 'insertionpoint) pts))
  11.         )
  12.       )
  13.     )
  14.   )
  15.   (princ))
« Last Edit: October 21, 2014, 03:06:12 PM by ronjonp »

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

Rabbit

  • Guest
Re: Changing anonymous block with another block
« Reply #4 on: October 21, 2014, 12:50:41 PM »
ronjonp,
You code didn't work.  Having cnt within the repeat command didn't work, so I brought that out in a different way.

But, the code crashes at the vl-some part.  I'm not familiar with vl-some enough to know what happened, but, I believe that it has something to do with if the parameter "AFF" is not in the block, then vl-some crashes.

I've attached the two blocks that I'm working with (R2012). I will eventually have to have the code work with both blocks.  In older drawings, "DaBlock" will be used.  In newer drawings, "DaBlockNew" will be used.  Biggest problem is that they both will have the same name "DaBlock".  I'm only using DaBlockNew to make it easier to work with here.  Hence why I'm looking for something that is different in the two so that the code can tell them apart.  Only thing I could think of was the missing parameter "AFF" would tell the code that it's working with an old block and it needs to be replaced by the new block.

Also, notice that the blocks have different insertion points.  As if the rest wasn't hard enough.


Here's you code showing what I did with the cnt. (lines 2-4 have changed)
Code - Auto/Visual Lisp: [Select]
  1. (defun c:foo (/ cnt e o pts xlist)
  2.   (if (setq cnt (sslength (setq xlist (ssget "X" (list (cons 0 "INSERT") (cons 2 "ELEVATION - NEW ORB,`*U*"))))))
  3.     (repeat (sslength xlist)
  4.       (setq cnt (1- cnt))
  5.       (if
  6.         (= (strcase
  7.              (vla-get-effectivename (setq o (vlax-ename->vla-object (setq e (ssname xlist cnt)))))
  8.            )
  9.            "ELEVATION - NEW ORB"
  10.         )
  11.          (if (vl-some (function (lambda (_prop) (= "BotORBToFlr" (strcase (vlax-get _prop 'name)))))
  12.                       (vlax-invoke o 'getdynamicblockproperties)
  13.              )
  14.            (entdel e)
  15.            (setq pts (cons (vlax-get o 'insertionpoint) pts))
  16.          )
  17.       )
  18.     )
  19.   )
  20.   (princ))
  21.  
  22.  

ronjonp

  • Needs a day job
  • Posts: 7526
Re: Changing anonymous block with another block
« Reply #5 on: October 21, 2014, 03:08:53 PM »
Maybe this ? All it does is delete blocks that have a dynamic property named 'AFF'. What are you doing with the insertion point (pts) list?
Code - Auto/Visual Lisp: [Select]
  1. (defun c:foo (/ e n o pts ss)
  2.   (if (setq ss (ssget "X" (list (cons 0 "INSERT") (cons 2 "dablock*,`*U*"))))
  3.     (repeat (setq n (sslength ss))
  4.       (setq o (vlax-ename->vla-object (setq e (ssname ss (setq n (1- n))))))
  5.       (if (wcmatch (strcase (vla-get-effectivename o)) "DABLOCK*")
  6.         (if (vl-some (function (lambda (_prop) (= "AFF" (strcase (vlax-get _prop 'propertyname)))))
  7.                      (vlax-invoke o 'getdynamicblockproperties)
  8.             )
  9.           (entdel e)
  10.           (setq pts (cons (vlax-get o 'insertionpoint) pts))
  11.         )
  12.       )
  13.     )
  14.   )
  15.   (princ)
  16. )

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

Lee Mac

  • Seagull
  • Posts: 12906
  • London, England
Re: Changing anonymous block with another block
« Reply #6 on: October 21, 2014, 03:14:53 PM »
If I've understood what you are looking to achieve, perhaps try the following:

Code: [Select]
(defun c:foo ( / blk dbp dif idx new obj prn prp ref rep sel spc tmp )
    (setq blk  "DaBlock"    ;; block name
          new  "DaBlockNew" ;; new block name
          prp  "AFF"        ;; dynamic block prop name
          dif  2759.336209736222 ;; insertion point difference
    )
    (cond
        (   (not
                (setq sel
                    (ssget "_X"
                        (list '(0 . "INSERT") (cons 2 (strcat "`*U*," blk))
                            (if (= 1 (getvar 'cvport))
                                (cons 410 (getvar 'ctab))
                               '(410 . "Model")
                            )
                        )
                    )
                )
            )
            (prompt (strcat "\nNo references of " blk " found in active drawing."))
        )
        (   (not (setq rep (LM:importblock new)))
            (prompt (strcat "\n" new " block not found."))
        )
        (   t
            (setq spc
                (vlax-get-property (vla-get-activedocument (vlax-get-acad-object))
                    (if (= 1 (getvar 'cvport))
                        'paperspace
                        'modelspace
                    )
                )
            )
            (repeat (setq idx (sslength sel))
                (if (and (setq obj (vlax-ename->vla-object (ssname sel (setq idx (1- idx)))))
                         (= (strcase blk) (strcase (vla-get-effectivename obj)))
                         (= :vlax-true (vla-get-isdynamicblock obj))
                         (setq dbp (vlax-invoke obj 'getdynamicblockproperties))
                         (setq dbp (mapcar '(lambda ( x ) (cons (strcase (vla-get-propertyname x)) x)) dbp))
                         (not (assoc (strcase prp) dbp))
                         (vlax-write-enabled-p obj)
                    )
                    (progn
                        (setq ref
                            (vla-insertblock spc
                                (vlax-3D-point
                                    (polar
                                        (vlax-get obj 'insertionpoint)
                                        (+ (/ pi 2.0) (vla-get-rotation obj))
                                        (- dif)
                                    )
                                )
                                rep
                                (vla-get-xscalefactor obj)
                                (vla-get-yscalefactor obj)
                                (vla-get-zscalefactor obj)
                                (vla-get-rotation obj)
                            )
                        )
                        (foreach prp '(layer color lineweight linetype)
                            (vlax-put-property ref prp (vlax-get-property obj prp))
                        )
                        (foreach prp (vlax-invoke ref 'getdynamicblockproperties)
                            (cond
                                (   (= "CLG" (setq prn (strcase (vla-get-propertyname prp))))
                                    (if (setq tmp (cdr (assoc "DISTANCE1" dbp)))
                                        (vla-put-value prp
                                            (vlax-make-variant (+ (vlax-get tmp 'value) dif)
                                                (vlax-variant-type (vla-get-value tmp))
                                            )
                                        )
                                    )
                                )
                                (   (= "VISIBILITY1" prn)
                                    (if (setq tmp (cdr (assoc "VISIBILITY1" dbp)))
                                        (vla-put-value prp (vla-get-value tmp))
                                    )
                                )
                            )
                        )
                    )
                )
            )
        )
    )
    (princ)
)

;; Import Block Definition  -  Lee Mac

(defun LM:importblock ( blk / bse cmd ext pth )
    (setq pth (vl-string-translate "/" "\\" (vl-filename-directory blk))
          ext (cond ((vl-filename-extension blk)) (".dwg"))
          bse (vl-filename-base blk)
    )
    (if (/= "" pth) (setq pth (strcat pth "\\")))
    (cond
        (   (tblsearch "block" bse) bse)
        (   (setq blk (findfile (strcat pth bse ext)))
            (setq cmd (getvar 'cmdecho))
            (setvar 'cmdecho 0)
            (command "_.-insert" blk nil)
            (setvar 'cmdecho cmd)
            (if (tblsearch "block" bse) bse)
        )
    )
)

(vl-load-com) (princ)

Rabbit

  • Guest
Re: Changing anonymous block with another block
« Reply #7 on: October 24, 2014, 02:38:38 PM »
Sorry for the late reply.  I've been trying to get something to work.  I almost had it, but it failed miserably and I'm back to square one.

ronjonp,  The point list is a list of all of the insertion points of the blocks I have gotten rid of.  Since I'm bringing in a new block, which has the same name as the old version, I'm having to erase the old blocks, rename any remaining that are nested in other blocks, then insert the new block at the insertion point of the old version.  The new version's insertion point is different that the old version's, therefore, I'm having to adjust the point list for that difference.

Lee,  As usual, your code amazes me.  When I first started looking at some of you code years ago, it might have been in some alien language that was totally illegible by me.  Where your mind goes to create this stuff is way beyond us mere mortals.  Now, with your patience, I am somewhat able follow along with what it's doing. Which scares me a little.  I can see what this code is doing, but I get lost in reverse engineering it.  I think what's getting me messed up is that your code assumes that the old block and the new block have separate names, when the fact is that the new block needs to replace the old one entirely.  Basically doing an insert from file and overwriting the old one, only the insert points need adjusting.  My first thought when trying to so this was to simple use
Code - Auto/Visual Lisp: [Select]
  1. (command "-insert" "c://Server//DaBlock.dwg" "non" InsertionPoint 1 1 0.0)
  But that doesn't allow to redefine the old block with the new.  I wasn't able to find an example on the web that would help me do this. Because of this, I decided the best thing was to just erase the old ones, keep a list of their insertion points, adjust as needed, and then reinsert.

The code I wrote fails if the renamed and new blocks are in the drawing together.  I am continuing exploring what each of you have taught me and see where it takes me.  I'm not going to post what I have right now, I'm having to rethink it.


Rabbit

  • Guest
Re: Changing anonymous block with another block
« Reply #8 on: October 24, 2014, 06:08:50 PM »
I got it to working.  I had to manipulate Lee's routine so that it can rename the old block at the beginning, then load the new block and go from there.  Works very well.  Thanks for the help guys.

Lee Mac

  • Seagull
  • Posts: 12906
  • London, England
Re: Changing anonymous block with another block
« Reply #9 on: October 24, 2014, 06:37:39 PM »
Thank you for your compliments Rabbit, I'm delighted to hear that you were able to tweak the code as required  8-)

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Changing anonymous block with another block
« Reply #10 on: October 25, 2014, 07:39:21 AM »
@ Lee:
Do you have a particular reason for not using the "_A" option of the ssget function?

IMO this:
Code: [Select]
(ssget "_X"
  (list '(0 . "INSERT") (cons 2 (strcat "`*U*," blk))
    (if (= 1 (getvar 'cvport))
      (cons 410 (getvar 'ctab))
       '(410 . "Model")
    )
  )
)
Can be replaced by:
Code: [Select]
(ssget "_A" (list '(0 . "INSERT") (cons 2 (strcat "`*U*," blk))))

Lee Mac

  • Seagull
  • Posts: 12906
  • London, England
Re: Changing anonymous block with another block
« Reply #11 on: October 25, 2014, 10:13:18 AM »
@ Lee: Do you have a particular reason for not using the "_A" option of the ssget function?

I thought the 'A' mode string excluded objects on frozen layers, I wasn't aware that this mode restricted the selection to the objects in the current viewport.

Lee

ribarm

  • Gator
  • Posts: 3225
  • Marko Ribar, architect
Re: Changing anonymous block with another block
« Reply #12 on: October 25, 2014, 10:36:26 AM »
Lee, I think you're right, the only difference between "_X" and "_A" mode is that "_A" mode excludes objects on frozen layers, and in both cases to be sure what's selected, you must provide 410 DXF code in selection filter...
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Changing anonymous block with another block
« Reply #13 on: October 26, 2014, 07:34:41 AM »
Aha, then there is a clear difference with BricsCAD's implementation of the "_A" option. In BricsCAD the "_A" option of the ssget function not only excludes objects on frozen layers (I forgot about that) but also objects that are not in the current space, making it ideal for selection sets for command calls. Thanks for the clarification (Lee) and confirmation (ribarm).

Rabbit

  • Guest
Re: Changing anonymous block with another block
« Reply #14 on: October 27, 2014, 10:57:23 AM »
Just for the sake of it,  how would I go about inserting a block into a drawing, from file, that redefines the existing, old block with the has the same name?  With that bit of knowledge, I might be able to slim down the code I have.  And, I might be able to use it in the future.