Author Topic: sssetfirst a nested entity inside a block?  (Read 5449 times)

0 Members and 1 Guest are viewing this topic.

zasanil

  • Guest
sssetfirst a nested entity inside a block?
« on: February 27, 2015, 02:20:57 PM »
Hello,
I am trying to learn simple autolisp and I am stuck at a certain function. I have a drawing with blocks and nested blocks inside of those. My code cycles through each block and then inside cycles through each entity. If it finds a nested block, I want to add that to the current selection set and then nburst it. My code is as follows:
Code: [Select]
  (while (setq SPI_CurrentSelection (tblnext "BLOCK" (not SPI_CurrentSelection))) ;cycle through BLOCKS
    (setq SPI_BlockEntitytName (cdr (assoc -2 SPI_CurrentSelection))) ;get name of FIRST entity inside block
      (while SPI_BlockEntitytName ;cycle through ENTITYS       
        (setq SPI_BlockEntity (entget SPI_BlockEntitytName)) ;get the full ENTITY
        (if (= "INSERT" (cdr (assoc 0 SPI_BlockEntity))) ;check if entity is an INSERT
          (progn
;;; <What to put here since NBURST needs something selected already?>
            (c:NBURST) ;NBURST selection
          ) ;_ end of progn
      ) ;_ end of if
      (setq SPI_BlockEntitytName (entnext SPI_BlockEntitytName))
    ) ;_ end of while
  ) ;_ end of while

Thanks for any help!

David Bethel

  • Swamp Rat
  • Posts: 656
Re: sssetfirst a nested entity inside a block?
« Reply #1 on: February 28, 2015, 07:00:43 AM »
Do I understand correctly ?  You want explode a nested block and keep the entities within the parent block ?

This could be an extremely complex problem.

What if the nested block :
  • is not WCS
  • its INSBASE is not '(0 0 0)
  • its rotation is not 0.0
  • its X Y & Z scales are not equal
  • it is a MINSERT
  • is not on LAyer 0
  • what to do with ATTRIButes

Translating all of factors would be daunting

-David
R12 Dos - A2K

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: sssetfirst a nested entity inside a block?
« Reply #2 on: February 28, 2015, 08:47:26 AM »
I am not sure what NBURST exactly does. But for nested entities you can use vla-explode:
Code: [Select]
(defun c:test ( / doc startP continueP)
  (vl-load-com)
  (setq doc (vla-get-activedocument (vlax-get-acad-object)))
  (if (= (logand (getvar 'undoctl) 8) 8)
    (vla-endundomark doc)
  )
  (vla-startundomark doc)
  (vlax-for blkDef (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))
    (if
      (and
        (= (vla-get-isxref blkDef) :vlax-false)
        (= (vla-get-islayout blkDef) :vlax-false)
      )
      (progn
        (setq startP T)
        (while (or startP continueP)
          (setq startP nil)
          (setq continueP nil)
          (vlax-for obj blkDef
            (if
              (and
                (= "AcDbBlockReference" (vla-get-objectname obj))
                (vlax-invoke obj 'explode)
              )
              (progn
                (vla-delete obj)
                (setq continueP T)
              )
            )
          )
        )
      )
    )
  )
  (vla-endundomark doc)
  (princ)
)

Edit: Improved code to account for multiple nesting levels.
« Last Edit: February 28, 2015, 09:17:50 AM by roy_043 »

zasanil

  • Guest
Re: sssetfirst a nested entity inside a block?
« Reply #3 on: February 28, 2015, 08:54:34 AM »
For the drawings I am working with these factors are not a concern. I can manually run the nburst without any issues. Trying to automate this I can't figure out how to select the nested block since to run the nburst command on a block it needs to be selected first. I know I need to use sssetfirst but I'm not sure how.

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: sssetfirst a nested entity inside a block?
« Reply #4 on: February 28, 2015, 09:21:18 AM »
I think you should clarify your intentions. I am now assuming that you want to keep the 'top level' inserts but want to explode nested inserts. But I may be mistaken.
Note that typically (Lisp) commands do not work on entities that are not in the current space.

Lee Mac

  • Seagull
  • Posts: 12906
  • London, England
Re: sssetfirst a nested entity inside a block?
« Reply #5 on: February 28, 2015, 09:59:49 AM »
Are you referring to my Nested Burst program?

zasanil

  • Guest
Re: sssetfirst a nested entity inside a block?
« Reply #6 on: February 28, 2015, 10:07:21 AM »
That's correct Lee, I'm trying to learn the lisp language by automating some stuff and one of the programs I use points to your nburst program. I can automate it in my program to select everything and burst, but if I was cycling through entities inside a block and came across a nested blocks and wanted to nburst a single one programatically, I would need it selected first. I am able to get the name of the insert and it's handle.

Lee Mac

  • Seagull
  • Posts: 12906
  • London, England
Re: sssetfirst a nested entity inside a block?
« Reply #7 on: February 28, 2015, 10:24:02 AM »
That's correct Lee, I'm trying to learn the lisp language by automating some stuff and one of the programs I use points to your nburst program. I can automate it in my program to select everything and burst, but if I was cycling through entities inside a block and came across a nested blocks and wanted to nburst a single one programatically, I would need it selected first. I am able to get the name of the insert and it's handle.

If I've correctly understood what you are looking to achieve, ensure my Nested Burst program is loaded & try the following:
Code: [Select]
(defun c:burstnested ( )
    (vlax-for blk (vla-get-blocks (LM:acdoc))
        (if (and (= :vlax-false (vla-get-islayout blk))
                 (= :vlax-false (vla-get-isxref blk))
                 (not (wcmatch  (vla-get-name blk) "`**"))
            )
            (vlax-map-collection blk 'LM:burstnested)
        )
    )
    (vla-regen (LM:acdoc) acallviewports)
    (princ)
)

zasanil

  • Guest
Re: sssetfirst a nested entity inside a block?
« Reply #8 on: February 28, 2015, 04:43:32 PM »
I think for now I was just wanting to learn how to sssetfirst a nested entity inside a block. I can set the entity to a variable and see the information about it, but I can't seem to make it selected.

Lee Mac

  • Seagull
  • Posts: 12906
  • London, England
Re: sssetfirst a nested entity inside a block?
« Reply #9 on: February 28, 2015, 06:09:12 PM »
I think for now I was just wanting to learn how to sssetfirst a nested entity inside a block. I can set the entity to a variable and see the information about it, but I can't seem to make it selected.

It is not possible to sssetfirst (i.e. select & grip) a nested entity.

zasanil

  • Guest
Re: sssetfirst a nested entity inside a block?
« Reply #10 on: February 28, 2015, 08:17:53 PM »
Ah dang. .that is a bummer. I'll give your code a try and see if that does what I need. Thanks!

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: sssetfirst a nested entity inside a block?
« Reply #11 on: March 01, 2015, 04:02:01 AM »
@ Lee:
A question about your (LM:endundo) function. Why do you use (while ...)? It is not possible to have nested undo groups. Well, at least it is not possible in BricsCAD.
Code: [Select]
(setq doc (vla-get-activedocument (vlax-get-acad-object)))

(getvar 'undoctl) => 5

(vla-startundomark doc)
(vla-startundomark doc)
(vla-startundomark doc)
(getvar 'undoctl) => 13

(vla-endundomark doc)
(getvar 'undoctl) => 5

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: sssetfirst a nested entity inside a block?
« Reply #12 on: March 02, 2015, 05:40:25 AM »
@ zasanil:
To select nested entities you can use nentsel.
The return value of nentsel provides information about the nesting of the entity:
Code: [Select]
(setq nestingList (cadddr (nentsel)))

zasanil

  • Guest
Re: sssetfirst a nested entity inside a block?
« Reply #13 on: March 02, 2015, 08:13:16 AM »
Lee,
If it's possible, how would I modify my code line to make the nburst take an variable "insert" as an argument? When you normally run nburst, it asks you to select something. If I already have an insert defined in the variable SPI_BlockEntity , how would I pass that to nburst instead?
I'm just starting out trying to learn Autolisp and haven't even begun to look at the vla side of things.

The section of my code is here:
Code: [Select]
(if (= "INSERT" (cdr (assoc 0 SPI_BlockEntity))) ;check if entity is an INSERT
     (progn
          (c:NBURST) ;NBURST SPI_BlockEntity
     ) ;_ end of progn
) ;_ end of if

Lee Mac

  • Seagull
  • Posts: 12906
  • London, England
Re: sssetfirst a nested entity inside a block?
« Reply #14 on: March 02, 2015, 08:47:03 AM »
how would I modify my code line to make the nburst take an variable "insert" as an argument? When you normally run nburst, it asks you to select something. If I already have an insert defined in the variable SPI_BlockEntity , how would I pass that to nburst instead?

The section of my code is here:
Code: [Select]
(if (= "INSERT" (cdr (assoc 0 SPI_BlockEntity))) ;check if entity is an INSERT
     (progn
          (c:NBURST) ;NBURST SPI_BlockEntity
     ) ;_ end of progn
) ;_ end of if

Firstly, note that your variable SPI_BlockEntity does not correspond to the entity name for an INSERT entity, but rather a static list of DXF data associated with the entity name (static in that, if the entity is modified, the list will not be updated; whereas an entity name is a pointer to the up-to-date DXF data in the drawing database). Therefore, you would need to use your SPI_BlockEntitytName variable.

My c:nburst function will evaluate the ssget function to prompt the user for a selection of block references, and will then iterate over this selection, convert each entity to a vla-object, and pass the vla-object to my LM:burstnested function for processing.

Hence, rather than attempting to make a selection of a nested entity (which is not possible), you should evaluate the LM:burstnested function directly (effectively cutting out the c:nburst middle-man - which is simply the user front-end for the program), supplying the required vla-object argument in the following way:

Code: [Select]
(if (= "INSERT" (cdr (assoc 0 SPI_BlockEntity))) ;check if entity is an INSERT
     (progn
          (LM:burstnested (vlax-ename->vla-object SPI_BlockEntitytName)) ;NBURST SPI_BlockEntity
     ) ;_ end of progn
) ;_ end of if